Contents: Computer Vision Project - 1

  1. Part-A: Solution
  2. Part-B: Solution

Part-A: Solution¶

  • DOMAIN: Botanical Research
  • CONTEXT: University X is currently undergoing some research involving understanding the characteristics of plant and plant seedlings at various stages of growth. They already have have invested on curating sample images. They require an automation which can create a classifier capable of determining a plant's species from a photo.
  • DATA DESCRIPTION: The dataset comprises of images from 12 plant species.

Source: https://www.kaggle.com/c/plant-seedlings-classification/data.

  • PROJECT OBJECTIVE: To create a classifier capable of determining a plant's species from a photo.
In [1]:
# Import all the relevant libraries needed to complete the analysis, visualization, modeling and presentation
import pandas as pd
import numpy as np
import os

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
sns.set_style('darkgrid')
%matplotlib inline

from scipy import stats
from scipy.stats import zscore

from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import RobustScaler
from sklearn import model_selection
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold, KFold
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report 
from sklearn.metrics import ConfusionMatrixDisplay, precision_score, recall_score 
from sklearn.metrics import precision_recall_curve, roc_curve, auc, roc_auc_score
from sklearn.metrics import plot_precision_recall_curve, average_precision_score
from sklearn.metrics import f1_score, plot_roc_curve 

from imblearn.over_sampling import RandomOverSampler
from imblearn.over_sampling import SMOTENC, SMOTE, ADASYN
from imblearn.under_sampling import RandomUnderSampler

import cv2
from google.colab.patches import cv2_imshow
from glob import glob
import itertools

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from tensorflow.keras.layers import Activation,GlobalMaxPool2D,GlobalAveragePooling2D
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.optimizers import Adam,RMSprop
from keras.utils.np_utils import to_categorical  
from keras.utils import np_utils
from tensorflow.keras.preprocessing.image import ImageDataGenerator

import warnings
warnings.filterwarnings("ignore")

import random

# pd.set_option('display.max_columns', None)
# pd.set_option('display.max_rows', None)
In [2]:
from google.colab import drive
drive.mount('/content/drive')
Mounted at /content/drive

1. Import and Understand the data¶

1A. Extract ‘plant-seedlings-classification.zip’ into new folder (unzipped) using python.¶

In [3]:
# Set the path to the dataset folder. (The dataset contains image folder: "train")
train_path = "/content/drive/MyDrive/MGL/Project-CV-1/plant-seedlings-classification.zip"

# Extract the files from dataset to train_temp
from zipfile import ZipFile
with ZipFile(train_path, 'r') as zip:
  zip.extractall('/content/drive/MyDrive/MGL/Project-CV-1/unzip-psc')

1B. Map the images from train folder with train labels to form a DataFrame.¶

  • Using Numpy array instead of dataframe as it is faster for image processing.
  • Converting images into numpy arrays is important, as the model accepts inputs in the form of numpy arrays.
In [4]:
# The path to all images in training set. (* means include all folders and files.)
path = "/content/drive/MyDrive/MGL/Project-CV-1/unzip-psc/plant-seedlings-classification/train/*/*.png"  
files = glob(path)

# Initialize empty list to store the image data as numbers.
X = []
# Initialize empty list to store the labels of images
y = [] 
j = 1
num = len(files)

# Collect images and labels in X and y
for img in files:
    '''
    Append the image data to X list.
    Append the labels to y list.
    '''
    print(str(j) + "/" + str(num), end="\r")
    # Get image (with resizing to 128 x 128)
    X.append(cv2.resize(cv2.imread(img), (128, 128))) 
    # Get image label (folder name contains the class to which the image belongs) 
    y.append(img.split('/')[-2])  
    j += 1

# Train images set
X = np.asarray(X) 
# Train labels set 
y = pd.DataFrame(y)  

In [5]:
# # Save the data
# np.save('/content/drive/MyDrive/MGL/Project-CV-1/X.npy', X)
# y.to_pickle('/content/drive/MyDrive/MGL/Project-CV-1/X.pkl')
In [6]:
# # Load the data
# X = np.load('/content/drive/MyDrive/MGL/Project-CV-1/X.npy')
# y = pd.read_pickle('/content/drive/MyDrive/MGL/Project-CV-1/X.pkl')
In [7]:
print(X.shape)
print(y.shape)
(4750, 128, 128, 3)
(4750, 1)
In [8]:
y[0].value_counts()
Out[8]:
Loose Silky-bent             654
Common Chickweed             611
Scentless Mayweed            516
Small-flowered Cranesbill    496
Fat Hen                      475
Charlock                     390
Sugar beet                   385
Cleavers                     287
Black-grass                  263
Shepherds Purse              231
Common wheat                 221
Maize                        221
Name: 0, dtype: int64

1C. Write a function that will select n random images and display images along with its species.¶

In [9]:
def random_images():
  r = random.randint(1, 200)

  f = plt.figure(figsize=(20, 20))

  f.add_subplot(2, 6, 1)
  plt.imshow(X[0+r])
  plt.title(y[0][0+r])

  f.add_subplot(2, 6, 2)
  plt.imshow(X[400+r])
  plt.title(y[0][400+r])

  f.add_subplot(2, 6, 3)
  plt.imshow(X[750+r])
  plt.title(y[0][750+r])
  
  f.add_subplot(2, 6, 4)
  plt.imshow(X[1300+r])
  plt.title(y[0][1300+r])

  f.add_subplot(2, 6, 5)
  plt.imshow(X[1700+r])
  plt.title(y[0][1700+r])

  f.add_subplot(2, 6, 6)
  plt.imshow(X[1600+r])
  plt.title(y[0][1600+r])

  f.add_subplot(1, 6, 1)
  plt.imshow(X[2400+r])
  plt.title(y[0][2400+r])

  f.add_subplot(1, 6, 2)
  plt.imshow(X[2630+r])
  plt.title(y[0][2630+r])

  f.add_subplot(1, 6, 3)
  plt.imshow(X[3000+r])
  plt.title(y[0][3000+r])
  
  f.add_subplot(1, 6, 4)
  plt.imshow(X[3200+r])
  plt.title(y[0][3200+r])

  f.add_subplot(1, 6, 5)
  plt.imshow(X[3538+r])
  plt.title(y[0][3538+r])

  f.add_subplot(1, 6, 6)
  plt.imshow(X[4500+r])
  plt.title(y[0][4500+r])

# Using the function to display 12 random images
random_images()
No description has been provided for this image

2. Data preprocessing¶

2A. Create X & Y from the DataFrame.¶

In [10]:
# This is completed in part 1B above.

2B. Encode labels of the images.¶

In [11]:
# Using LabelEncoder from preprocessing
labels = preprocessing.LabelEncoder()
labels.fit(y[0])
print('Classes'+str(labels.classes_))
Classes['Black-grass' 'Charlock' 'Cleavers' 'Common Chickweed' 'Common wheat'
 'Fat Hen' 'Loose Silky-bent' 'Maize' 'Scentless Mayweed'
 'Shepherds Purse' 'Small-flowered Cranesbill' 'Sugar beet']
In [12]:
encodedLabel = labels.transform(y[0])
convertedLabels = np_utils.to_categorical(encodedLabel)
classes = convertedLabels.shape[1]
print(str(classes))
12

2C. Unify shape of all the images.¶

In [13]:
# This is completed in part 1B above.
# All images have been resized to (128, 128, 3).

2D. Normalise all the images.¶

In [14]:
# Normalization of images
X = X.astype('float32') / 255.0

3. Model training¶

  • 3A. Split the data into train and test data.
  • 3B. Create new CNN architecture to train the model
  • 3C. Train the model on train data and validate on test data.
  • 3D. Select a random image and print actual label and predicted label for the same.

Due to time constraint, I am using small number of epochs, and training only the model-1. Similar process can be replicated for other complex models (From Model-2 to Model-5).

In [15]:
# Shape of the dataset
print(X.shape)
print(y.shape)
(4750, 128, 128, 3)
(4750, 1)
In [16]:
# Split X and y into train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X, convertedLabels, test_size=0.3, random_state=0, stratify=convertedLabels)
In [17]:
# Shape of train and test datasets
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
(3325, 128, 128, 3)
(3325, 12)
(1425, 128, 128, 3)
(1425, 12)
In [18]:
labels.classes_[0], labels.classes_[1], labels.classes_[11]
Out[18]:
('Black-grass', 'Charlock', 'Sugar beet')
In [19]:
labels.classes_
Out[19]:
array(['Black-grass', 'Charlock', 'Cleavers', 'Common Chickweed',
       'Common wheat', 'Fat Hen', 'Loose Silky-bent', 'Maize',
       'Scentless Mayweed', 'Shepherds Purse',
       'Small-flowered Cranesbill', 'Sugar beet'], dtype=object)
In [20]:
plt.imshow(X_train[0])
Out[20]:
<matplotlib.image.AxesImage at 0x7ff2a555a710>
No description has been provided for this image
In [21]:
y_train[0]
Out[21]:
array([0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
In [22]:
plt.imshow(X_test[0])
Out[22]:
<matplotlib.image.AxesImage at 0x7ff2a554d110>
No description has been provided for this image
In [23]:
y_test[0]
Out[23]:
array([0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)

Model-1¶

  • 2 convolution layers ( filters=64 / 128 , kernel_size=(3, 3) activation='relu')
  • MaxPool2D((2, 2)
  • Dropout(0.25)
  • Flatten
  • 2 dense layers (128 / 64, activation='relu')
  • Dropout(0.25)
  • loss='categorical_crossentropy', optimizer='adam'
  • model compile with ImageDataGenerator to minimize overfitting.
  • shuffle = True
In [24]:
generator = ImageDataGenerator(rotation_range = 180,
                               zoom_range = 0.2,
                               width_shift_range = 0.2,
                               height_shift_range = 0.2,
                               horizontal_flip = True,
                               vertical_flip = True)
generator.fit(X_train)
In [25]:
model1 = Sequential()

model1.add(Conv2D(filters=64, kernel_size=(3, 3), input_shape=(128, 128, 3), activation='relu'))
model1.add(MaxPool2D((2, 2)))
model1.add(Dropout(0.25))

model1.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
model1.add(MaxPool2D((2, 2)))
model1.add(Dropout(0.25))

model1.add(Flatten())

model1.add(Dense(128, activation='relu'))
model1.add(Dropout(0.25))

model1.add(Dense(64, activation='relu'))
model1.add(Dropout(0.25))

model1.add(Dense(classes, activation='softmax'))

model1.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

model1.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 126, 126, 64)      1792      
                                                                 
 max_pooling2d (MaxPooling2D  (None, 63, 63, 64)       0         
 )                                                               
                                                                 
 dropout (Dropout)           (None, 63, 63, 64)        0         
                                                                 
 conv2d_1 (Conv2D)           (None, 61, 61, 128)       73856     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 30, 30, 128)      0         
 2D)                                                             
                                                                 
 dropout_1 (Dropout)         (None, 30, 30, 128)       0         
                                                                 
 flatten (Flatten)           (None, 115200)            0         
                                                                 
 dense (Dense)               (None, 128)               14745728  
                                                                 
 dropout_2 (Dropout)         (None, 128)               0         
                                                                 
 dense_1 (Dense)             (None, 64)                8256      
                                                                 
 dropout_3 (Dropout)         (None, 64)                0         
                                                                 
 dense_2 (Dense)             (None, 12)                780       
                                                                 
=================================================================
Total params: 14,830,412
Trainable params: 14,830,412
Non-trainable params: 0
_________________________________________________________________
In [26]:
history1 = model1.fit(generator.flow(X_train,y_train,batch_size=200), epochs=50, verbose=2, shuffle=True, validation_data=(X_test,y_test))
pd.DataFrame(history1.history)
Epoch 1/50
17/17 - 209s - loss: 2.6994 - accuracy: 0.1053 - val_loss: 2.4601 - val_accuracy: 0.1046 - 209s/epoch - 12s/step
Epoch 2/50
17/17 - 211s - loss: 2.4540 - accuracy: 0.1287 - val_loss: 2.4256 - val_accuracy: 0.2765 - 211s/epoch - 12s/step
Epoch 3/50
17/17 - 205s - loss: 2.3883 - accuracy: 0.1832 - val_loss: 2.2750 - val_accuracy: 0.2428 - 205s/epoch - 12s/step
Epoch 4/50
17/17 - 200s - loss: 2.2630 - accuracy: 0.2241 - val_loss: 2.1172 - val_accuracy: 0.2646 - 200s/epoch - 12s/step
Epoch 5/50
17/17 - 204s - loss: 2.1503 - accuracy: 0.2517 - val_loss: 1.9697 - val_accuracy: 0.2835 - 204s/epoch - 12s/step
Epoch 6/50
17/17 - 202s - loss: 2.0408 - accuracy: 0.2644 - val_loss: 1.8675 - val_accuracy: 0.3116 - 202s/epoch - 12s/step
Epoch 7/50
17/17 - 204s - loss: 1.9725 - accuracy: 0.2875 - val_loss: 1.7994 - val_accuracy: 0.3291 - 204s/epoch - 12s/step
Epoch 8/50
17/17 - 206s - loss: 1.9066 - accuracy: 0.3242 - val_loss: 1.7073 - val_accuracy: 0.4168 - 206s/epoch - 12s/step
Epoch 9/50
17/17 - 203s - loss: 1.8552 - accuracy: 0.3441 - val_loss: 1.6390 - val_accuracy: 0.4681 - 203s/epoch - 12s/step
Epoch 10/50
17/17 - 208s - loss: 1.7791 - accuracy: 0.3756 - val_loss: 1.5939 - val_accuracy: 0.4842 - 208s/epoch - 12s/step
Epoch 11/50
17/17 - 203s - loss: 1.7312 - accuracy: 0.3877 - val_loss: 1.5332 - val_accuracy: 0.4947 - 203s/epoch - 12s/step
Epoch 12/50
17/17 - 203s - loss: 1.7123 - accuracy: 0.3967 - val_loss: 1.5543 - val_accuracy: 0.4772 - 203s/epoch - 12s/step
Epoch 13/50
17/17 - 209s - loss: 1.6549 - accuracy: 0.4087 - val_loss: 1.4451 - val_accuracy: 0.5270 - 209s/epoch - 12s/step
Epoch 14/50
17/17 - 201s - loss: 1.6210 - accuracy: 0.4292 - val_loss: 1.4125 - val_accuracy: 0.5396 - 201s/epoch - 12s/step
Epoch 15/50
17/17 - 201s - loss: 1.6307 - accuracy: 0.4214 - val_loss: 1.3606 - val_accuracy: 0.5396 - 201s/epoch - 12s/step
Epoch 16/50
17/17 - 210s - loss: 1.5873 - accuracy: 0.4406 - val_loss: 1.4518 - val_accuracy: 0.5088 - 210s/epoch - 12s/step
Epoch 17/50
17/17 - 201s - loss: 1.5843 - accuracy: 0.4436 - val_loss: 1.5021 - val_accuracy: 0.4835 - 201s/epoch - 12s/step
Epoch 18/50
17/17 - 202s - loss: 1.5950 - accuracy: 0.4451 - val_loss: 1.4328 - val_accuracy: 0.5249 - 202s/epoch - 12s/step
Epoch 19/50
17/17 - 203s - loss: 1.5372 - accuracy: 0.4556 - val_loss: 1.3732 - val_accuracy: 0.5467 - 203s/epoch - 12s/step
Epoch 20/50
17/17 - 201s - loss: 1.5390 - accuracy: 0.4517 - val_loss: 1.4163 - val_accuracy: 0.5460 - 201s/epoch - 12s/step
Epoch 21/50
17/17 - 206s - loss: 1.5160 - accuracy: 0.4650 - val_loss: 1.4135 - val_accuracy: 0.5291 - 206s/epoch - 12s/step
Epoch 22/50
17/17 - 202s - loss: 1.4974 - accuracy: 0.4725 - val_loss: 1.4197 - val_accuracy: 0.5214 - 202s/epoch - 12s/step
Epoch 23/50
17/17 - 201s - loss: 1.4951 - accuracy: 0.4731 - val_loss: 1.3136 - val_accuracy: 0.5628 - 201s/epoch - 12s/step
Epoch 24/50
17/17 - 206s - loss: 1.4980 - accuracy: 0.4788 - val_loss: 1.4102 - val_accuracy: 0.5172 - 206s/epoch - 12s/step
Epoch 25/50
17/17 - 201s - loss: 1.4983 - accuracy: 0.4719 - val_loss: 1.2956 - val_accuracy: 0.5670 - 201s/epoch - 12s/step
Epoch 26/50
17/17 - 201s - loss: 1.4553 - accuracy: 0.4881 - val_loss: 1.3105 - val_accuracy: 0.5684 - 201s/epoch - 12s/step
Epoch 27/50
17/17 - 210s - loss: 1.4491 - accuracy: 0.4854 - val_loss: 1.2760 - val_accuracy: 0.5818 - 210s/epoch - 12s/step
Epoch 28/50
17/17 - 203s - loss: 1.4368 - accuracy: 0.5020 - val_loss: 1.2311 - val_accuracy: 0.5930 - 203s/epoch - 12s/step
Epoch 29/50
17/17 - 202s - loss: 1.4303 - accuracy: 0.5011 - val_loss: 1.3631 - val_accuracy: 0.5404 - 202s/epoch - 12s/step
Epoch 30/50
17/17 - 208s - loss: 1.4500 - accuracy: 0.4968 - val_loss: 1.3641 - val_accuracy: 0.5368 - 208s/epoch - 12s/step
Epoch 31/50
17/17 - 200s - loss: 1.4527 - accuracy: 0.4878 - val_loss: 1.1803 - val_accuracy: 0.6147 - 200s/epoch - 12s/step
Epoch 32/50
17/17 - 208s - loss: 1.4251 - accuracy: 0.4971 - val_loss: 1.2480 - val_accuracy: 0.5747 - 208s/epoch - 12s/step
Epoch 33/50
17/17 - 202s - loss: 1.3643 - accuracy: 0.5209 - val_loss: 1.1968 - val_accuracy: 0.5979 - 202s/epoch - 12s/step
Epoch 34/50
17/17 - 200s - loss: 1.3601 - accuracy: 0.5203 - val_loss: 1.1619 - val_accuracy: 0.6175 - 200s/epoch - 12s/step
Epoch 35/50
17/17 - 205s - loss: 1.3874 - accuracy: 0.5056 - val_loss: 1.1757 - val_accuracy: 0.6140 - 205s/epoch - 12s/step
Epoch 36/50
17/17 - 204s - loss: 1.3395 - accuracy: 0.5359 - val_loss: 1.2142 - val_accuracy: 0.5958 - 204s/epoch - 12s/step
Epoch 37/50
17/17 - 200s - loss: 1.3118 - accuracy: 0.5398 - val_loss: 1.1981 - val_accuracy: 0.6175 - 200s/epoch - 12s/step
Epoch 38/50
17/17 - 206s - loss: 1.3352 - accuracy: 0.5438 - val_loss: 1.1624 - val_accuracy: 0.6253 - 206s/epoch - 12s/step
Epoch 39/50
17/17 - 202s - loss: 1.3074 - accuracy: 0.5513 - val_loss: 1.2151 - val_accuracy: 0.5951 - 202s/epoch - 12s/step
Epoch 40/50
17/17 - 203s - loss: 1.2999 - accuracy: 0.5474 - val_loss: 1.2887 - val_accuracy: 0.5607 - 203s/epoch - 12s/step
Epoch 41/50
17/17 - 202s - loss: 1.2792 - accuracy: 0.5498 - val_loss: 1.1206 - val_accuracy: 0.6456 - 202s/epoch - 12s/step
Epoch 42/50
17/17 - 199s - loss: 1.2885 - accuracy: 0.5552 - val_loss: 1.1700 - val_accuracy: 0.6140 - 199s/epoch - 12s/step
Epoch 43/50
17/17 - 205s - loss: 1.2574 - accuracy: 0.5657 - val_loss: 1.0588 - val_accuracy: 0.6589 - 205s/epoch - 12s/step
Epoch 44/50
17/17 - 201s - loss: 1.2285 - accuracy: 0.5618 - val_loss: 1.0346 - val_accuracy: 0.6582 - 201s/epoch - 12s/step
Epoch 45/50
17/17 - 199s - loss: 1.2108 - accuracy: 0.5795 - val_loss: 1.0652 - val_accuracy: 0.6498 - 199s/epoch - 12s/step
Epoch 46/50
17/17 - 202s - loss: 1.2256 - accuracy: 0.5735 - val_loss: 1.0164 - val_accuracy: 0.6779 - 202s/epoch - 12s/step
Epoch 47/50
17/17 - 204s - loss: 1.1983 - accuracy: 0.5808 - val_loss: 0.9655 - val_accuracy: 0.6814 - 204s/epoch - 12s/step
Epoch 48/50
17/17 - 200s - loss: 1.1816 - accuracy: 0.5859 - val_loss: 0.9662 - val_accuracy: 0.6793 - 200s/epoch - 12s/step
Epoch 49/50
17/17 - 206s - loss: 1.1667 - accuracy: 0.5997 - val_loss: 1.0452 - val_accuracy: 0.6491 - 206s/epoch - 12s/step
Epoch 50/50
17/17 - 200s - loss: 1.1515 - accuracy: 0.5946 - val_loss: 1.0238 - val_accuracy: 0.6575 - 200s/epoch - 12s/step
Out[26]:
loss accuracy val_loss val_accuracy
0 2.699441 0.105263 2.460149 0.104561
1 2.453981 0.128722 2.425604 0.276491
2 2.388316 0.183158 2.275042 0.242807
3 2.263000 0.224060 2.117186 0.264561
4 2.150331 0.251729 1.969655 0.283509
5 2.040815 0.264361 1.867471 0.311579
6 1.972471 0.287519 1.799362 0.329123
7 1.906564 0.324211 1.707271 0.416842
8 1.855207 0.344060 1.639012 0.468070
9 1.779057 0.375639 1.593907 0.484211
10 1.731201 0.387669 1.533185 0.494737
11 1.712253 0.396692 1.554253 0.477193
12 1.654895 0.408722 1.445120 0.527018
13 1.620960 0.429173 1.412478 0.539649
14 1.630711 0.421353 1.360565 0.539649
15 1.587285 0.440601 1.451784 0.508772
16 1.584279 0.443609 1.502104 0.483509
17 1.595046 0.445113 1.432792 0.524912
18 1.537174 0.455639 1.373236 0.546667
19 1.538957 0.451729 1.416279 0.545965
20 1.516031 0.464962 1.413470 0.529123
21 1.497383 0.472481 1.419745 0.521403
22 1.495136 0.473083 1.313640 0.562807
23 1.498047 0.478797 1.410162 0.517193
24 1.498272 0.471880 1.295603 0.567018
25 1.455293 0.488120 1.310506 0.568421
26 1.449106 0.485414 1.275987 0.581754
27 1.436789 0.501955 1.231126 0.592982
28 1.430310 0.501053 1.363055 0.540351
29 1.449984 0.496842 1.364147 0.536842
30 1.452696 0.487820 1.180346 0.614737
31 1.425145 0.497143 1.248036 0.574737
32 1.364349 0.520902 1.196798 0.597895
33 1.360124 0.520301 1.161936 0.617544
34 1.387362 0.505564 1.175725 0.614035
35 1.339469 0.535940 1.214247 0.595789
36 1.311847 0.539850 1.198147 0.617544
37 1.335180 0.543759 1.162438 0.625263
38 1.307360 0.551278 1.215080 0.595088
39 1.299950 0.547368 1.288730 0.560702
40 1.279231 0.549774 1.120554 0.645614
41 1.288534 0.555188 1.169995 0.614035
42 1.257393 0.565714 1.058822 0.658947
43 1.228451 0.561805 1.034582 0.658246
44 1.210798 0.579549 1.065235 0.649825
45 1.225574 0.573534 1.016358 0.677895
46 1.198300 0.580752 0.965505 0.681404
47 1.181645 0.585865 0.966233 0.679298
48 1.166720 0.599699 1.045205 0.649123
49 1.151458 0.594586 1.023830 0.657544
In [27]:
# Capturing learning history per epoch
hist  = pd.DataFrame(history1.history)
hist['epoch'] = history1.epoch

# Plotting accuracy at different epochs
plt.plot(hist['loss'])
plt.plot(hist['val_loss'])
plt.legend(("train" , "valid") , loc =0)

# Printing results
results = model1.evaluate(X_test, y_test)
45/45 [==============================] - 18s 405ms/step - loss: 1.0238 - accuracy: 0.6575
No description has been provided for this image
In [28]:
# Capturing learning history per epoch
hist  = pd.DataFrame(history1.history)
hist['epoch'] = history1.epoch

# Plotting accuracy at different epochs
plt.plot(hist['accuracy'])
plt.plot(hist['val_accuracy'])
plt.legend(("train" , "valid") , loc =0)

# Printing results
results = model1.evaluate(X_test, y_test)
45/45 [==============================] - 18s 405ms/step - loss: 1.0238 - accuracy: 0.6575
No description has been provided for this image
In [29]:
y_pred=model1.predict(X_test)
y_pred
45/45 [==============================] - 18s 404ms/step
Out[29]:
array([[1.7538852e-04, 2.9225720e-04, 5.8182035e-05, ..., 4.0803514e-02,
        1.3137973e-02, 1.4122833e-03],
       [1.1852717e-03, 7.9621606e-02, 2.2754803e-01, ..., 8.8252835e-03,
        1.8610634e-02, 4.2275268e-01],
       [5.5335499e-06, 1.7435183e-06, 7.8689389e-08, ..., 1.5939398e-03,
        1.1415473e-03, 2.5502441e-05],
       ...,
       [1.1424939e-05, 6.2609111e-06, 2.7024404e-07, ..., 3.5962116e-03,
        9.6176489e-04, 4.3383185e-05],
       [4.3460182e-05, 1.4543781e-02, 2.1688105e-04, ..., 2.5651562e-01,
        1.7420383e-01, 1.3956984e-02],
       [1.7664894e-05, 1.5756009e-04, 2.9902756e-06, ..., 6.6294044e-02,
        7.0197952e-01, 2.5368039e-03]], dtype=float32)
In [30]:
# Classification Accuracy
print("Classification Accuracy:")
print('Loss and Accuracy on Training data:',model1.evaluate(X_train, y_train))
print('Loss and Accuracy on Test data:',model1.evaluate(X_test, y_test))
print()

# Classification Report
print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# Confusion Matrix
print("Confusion Matrix Chart:")
cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
df_cm = pd.DataFrame(cm, index = [i for i in [labels.classes_]],  
                         columns = [i for i in [labels.classes_]])
plt.figure(figsize = (12,10))
sns.heatmap(df_cm, annot=True, fmt='g')
plt.title('Confusion Matrix')
plt.ylabel('Actual Label')
plt.xlabel('Predicted Label')
plt.show()
Classification Accuracy:
104/104 [==============================] - 42s 408ms/step - loss: 1.0074 - accuracy: 0.6418
Loss and Accuracy on Training data: [1.0074156522750854, 0.6418045163154602]
45/45 [==============================] - 20s 441ms/step - loss: 1.0238 - accuracy: 0.6575
Loss and Accuracy on Test data: [1.0238300561904907, 0.6575438380241394]

Classification Report:
               precision    recall  f1-score   support

           0       0.00      0.00      0.00        79
           1       0.68      0.86      0.76       117
           2       0.74      0.67      0.71        86
           3       0.69      0.95      0.80       183
           4       0.78      0.64      0.70        66
           5       0.62      0.36      0.46       143
           6       0.72      0.87      0.79       196
           7       0.52      0.80      0.63        66
           8       0.58      0.63      0.60       155
           9       0.48      0.20      0.29        69
          10       0.66      0.70      0.68       149
          11       0.61      0.62      0.61       116

    accuracy                           0.66      1425
   macro avg       0.59      0.61      0.59      1425
weighted avg       0.62      0.66      0.62      1425

Confusion Matrix Chart:
No description has been provided for this image

Evaluation metrics allow us to estimate errors to determine how well our models are performing:

Accuracy: ratio of correct predictions over total predictions.

Precision: how often the classifier is correct when it predicts positive.

Recall: how often the classifier is correct for all positive instances.

F-Score: single measurement to combine precision and recall.

Considering the Class Recall, Precision, F1 Score and Accuracy as the most important parameters to decide the best model for this problem. We may have higher values in the below models here. Please refer the other models for the same.

  • A decent performance is visible from the above metrics.
  • As evident, Model-1 is not overfitting, we can use more complex models to improve the performance.
  • A Balanced dataset will be more benefcial in our case.
  • The number of features in the image dataset are huge compared to the number of examples, this is a challenge for DNNs and CNNs.
  • To overcome overfitting, we can use data augmentation, batch normalization, and transfer learning.

Predicting the class of a single image:¶

In [31]:
# Using test images from the given dataset
# Test Image as n1
n1 = 51
plt.imshow(X_test[n1])

# y_pred=model1.predict(X_test)

# Actual Class
print("Actual Class: ",labels.classes_[y_test.argmax(axis=1)[n1]])
# Predicted Class
print("Predicted Class: ",labels.classes_[y_pred.argmax(axis=1)[n1]])
Actual Class:  Small-flowered Cranesbill
Predicted Class:  Small-flowered Cranesbill
No description has been provided for this image

Additional Models; Not part of the Project Part-A:

Model-2¶

  • 3 convolution layers (filters=64/128/128 , kernel_size=(3, 3) activation='relu')
  • MaxPool2D((2, 2),
  • Dropout(0.25)
  • Flatten
  • 1 dense layer (256, activation='relu')
  • Dropout(0.5)
  • loss='categorical_crossentropy', optimizer='adam'
  • model compile with ImageDataGenerator to minimize overfitting.
  • shuffle = True
In [32]:
# generator = ImageDataGenerator(rotation_range = 180,
#                                zoom_range = 0.2,
#                                width_shift_range = 0.2,
#                                height_shift_range = 0.2,
#                                horizontal_flip = True,
#                                vertical_flip = True)
# generator.fit(X_train)
In [33]:
# model2 = Sequential()

# model2.add(Conv2D(filters=64, kernel_size=(3, 3), input_shape=(128, 128, 3), activation='relu'))
# model2.add(MaxPool2D((2, 2)))
# model2.add(Dropout(0.25))

# model2.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
# model2.add(MaxPool2D((2, 2)))
# model2.add(Dropout(0.25))

# model2.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
# model2.add(MaxPool2D((2, 2)))
# model2.add(Dropout(0.25))

# model2.add(Flatten())

# model2.add(Dense(256, activation='relu'))
# model2.add(Dropout(0.5))

# model2.add(Dense(classes, activation='softmax'))

# model2.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# model2.summary()
In [34]:
# history2 = model2.fit(generator.flow(X_train,y_train,batch_size=64),epochs=100, verbose=2,shuffle=True,validation_data=(X_test,y_test))
# pd.DataFrame(history2.history)
In [35]:
# # Plotting Train Loss vs Validation Loss
# plt.plot(history2.history['loss'])
# plt.plot(history2.history['val_loss'])
# plt.title('model loss')
# plt.ylabel('Loss')
# plt.xlabel('Epoch')
# plt.legend(['train', 'validation'], loc='upper left')
# plt.show()
In [36]:
# # Capturing learning history per epoch
# hist  = pd.DataFrame(history2.history)
# hist['epoch'] = history2.epoch

# # Plotting accuracy at different epochs
# plt.plot(hist['accuracy'])
# plt.plot(hist['val_accuracy'])
# plt.legend(("train" , "valid") , loc =0)

# # Printing results
# results = model2.evaluate(X_test, y_test)
In [37]:
# y_pred=model2.predict(X_test)
# y_pred
In [38]:
# # Classification Accuracy
# print("Classification Accuracy:")
# print('Loss and Accuracy on Training data:',model2.evaluate(X_train, y_train))
# print('Loss and Accuracy on Test data:',model2.evaluate(X_test, y_test))
# print()

# # Classification Report
# print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# # Confusion Matrix
# print("Confusion Matrix Chart:")
# cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
# df_cm = pd.DataFrame(cm, index = [i for i in [labels.classes_]],  
#                          columns = [i for i in [labels.classes_]])
# plt.figure(figsize = (12,10))
# sns.heatmap(df_cm, annot=True, fmt='g')
# plt.title('Confusion Matrix')
# plt.ylabel('Actual Label')
# plt.xlabel('Predicted Label')
# plt.show()

Model-3¶

  • 4 convolution layers (filters=64/64/128/256, kernel_size=(3, 3) activation='relu')
  • MaxPool2D((2, 2)
  • Dropout(0.25)
  • GlobalMaxPool2D
  • Flatten
  • 2 dense layers (256 / 256, activation='relu')
  • Dropout(0.25)
  • loss='categorical_crossentropy', optimizer='adam'
  • model compile with ImageDataGenerator to minimize overfitting.
  • shuffle = True
In [39]:
# model3 = Sequential()

# model3.add(Conv2D(filters=64, kernel_size=(3, 3), input_shape=(128, 128, 3), activation='relu'))
# model3.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
# model3.add(MaxPool2D((2, 2)))
# model3.add(Dropout(0.25))

# model3.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
# model3.add(MaxPool2D((2, 2)))
# model3.add(Dropout(0.25))

# model3.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu'))
# model3.add(MaxPool2D((2, 2)))
# model3.add(Dropout(0.25))

# model3.add(GlobalMaxPool2D())

# model3.add(Flatten())

# model3.add(Dense(256, activation='relu'))
# model3.add(Dropout(0.25))

# model3.add(Dense(256, activation='relu'))
# model3.add(Dropout(0.25))

# model3.add(Dense(classes, activation='softmax'))

# model3.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# model3.summary()
In [40]:
# history3 = model3.fit(generator.flow(X_train,y_train,batch_size=64),epochs=200, verbose=2,shuffle=True,validation_data=(X_test,y_test))
# pd.DataFrame(history3.history)
In [41]:
# # Plotting Train Loss vs Validation Loss
# plt.plot(history3.history['loss'])
# plt.plot(history3.history['val_loss'])
# plt.title('model loss')
# plt.ylabel('Loss')
# plt.xlabel('Epoch')
# plt.legend(['train', 'validation'], loc='upper left')
# plt.show()
In [42]:
# # Capturing learning history per epoch
# hist  = pd.DataFrame(history3.history)
# hist['epoch'] = history3.epoch

# # Plotting accuracy at different epochs
# plt.plot(hist['accuracy'])
# plt.plot(hist['val_accuracy'])
# plt.legend(("train" , "valid") , loc =0)

# # Printing results
# results = model3.evaluate(X_test, y_test)
In [43]:
# y_pred=model3.predict(X_test)
# y_pred
In [44]:
# # Classification Accuracy
# print("Classification Accuracy:")
# print('Loss and Accuracy on Training data:',model3.evaluate(X_train, y_train))
# print('Loss and Accuracy on Test data:',model3.evaluate(X_test, y_test))
# print()

# # Classification Report
# print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# # Confusion Matrix
# print("Confusion Matrix Chart:")
# cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
# df_cm = pd.DataFrame(cm, index = [i for i in [labels.classes_]],  
#                          columns = [i for i in [labels.classes_]])
# plt.figure(figsize = (12,10))
# sns.heatmap(df_cm, annot=True, fmt='g')
# plt.title('Confusion Matrix')
# plt.ylabel('Actual Label')
# plt.xlabel('Predicted Label')
# plt.show()

Model-4¶

  • 6 convolution layers (filters=64/64/128/128/256/256, kernel_size=(3, 3) activation='relu')
  • MaxPool2D((2, 2)
  • Dropout(0.25)
  • GlobalMaxPool2D
  • Flatten
  • 3 dense layers (256/256/256, activation='relu')
  • Dropout(0.25)
  • loss='categorical_crossentropy', optimizer='adam'
  • model compile with ImageDataGenerator to minimize overfitting.
  • shuffle = True
In [45]:
# generator = ImageDataGenerator(rotation_range = 180,
#                                zoom_range = 0.2,
#                                width_shift_range = 0.2,
#                                height_shift_range = 0.2,
#                                horizontal_flip = True,
#                                vertical_flip = True)
# generator.fit(X_train)
In [46]:
# model4 = Sequential()

# model4.add(Conv2D(filters=64, kernel_size=(3, 3), input_shape=(128, 128, 3), activation='relu'))
# model4.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
# model4.add(MaxPool2D((2, 2)))
# model4.add(Dropout(0.25))

# model4.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
# model4.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
# model4.add(MaxPool2D((2, 2)))
# model4.add(Dropout(0.25))

# model4.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu'))
# model4.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu'))
# model4.add(MaxPool2D((2, 2)))
# model4.add(Dropout(0.25))

# model4.add(GlobalMaxPool2D())

# model4.add(Flatten())

# model4.add(Dense(256, activation='relu'))
# model4.add(Dropout(0.25))

# model4.add(Dense(256, activation='relu'))
# model4.add(Dropout(0.25))

# model4.add(Dense(256, activation='relu'))
# model4.add(Dropout(0.25))

# model4.add(Dense(classes, activation='softmax'))

# model4.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# model4.summary()
In [47]:
# history4 = model4.fit(generator.flow(X_train,y_train,batch_size=64),epochs=200, verbose=2,shuffle=True,validation_data=(X_test,y_test))
# pd.DataFrame(history4.history)
In [48]:
# #Plotting Train Loss vs Validation Loss
# plt.plot(history4.history['loss'])
# plt.plot(history4.history['val_loss'])
# plt.title('model loss')
# plt.ylabel('Loss')
# plt.xlabel('Epoch')
# plt.legend(['train', 'validation'], loc='upper left')
# plt.show()
In [49]:
# # Capturing learning history per epoch
# hist  = pd.DataFrame(history4.history)
# hist['epoch'] = history4.epoch

# # Plotting accuracy at different epochs
# plt.plot(hist['accuracy'])
# plt.plot(hist['val_accuracy'])
# plt.legend(("train" , "valid") , loc =0)

# # Printing results
# results = model4.evaluate(X_test, y_test)
In [50]:
# y_pred=model4.predict(X_test)
# y_pred
In [51]:
# # Classification Accuracy
# print("Classification Accuracy:")
# print('Loss and Accuracy on Training data:',model4.evaluate(X_train, y_train))
# print('Loss and Accuracy on Test data:',model4.evaluate(X_test, y_test))
# print()

# # Classification Report
# print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# # Confusion Matrix
# print("Confusion Matrix Chart:")
# cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
# df_cm = pd.DataFrame(cm, index = [i for i in [labels.classes_]],  
#                          columns = [i for i in [labels.classes_]])
# plt.figure(figsize = (12,10))
# sns.heatmap(df_cm, annot=True, fmt='g')
# plt.title('Confusion Matrix')
# plt.ylabel('Actual Label')
# plt.xlabel('Predicted Label')
# plt.show()

Model-5¶

In [52]:
# # Initialize the object of ImageDataGenerator
# datagen= tf.keras.preprocessing.image.ImageDataGenerator(rotation_range=20,
#                                                          width_shift_range=0.2,
#                                                          height_shift_range=0.2,
#                                                          zoom_range=[0.4,1.5],
#                                                          horizontal_flip=True,
#                                                          vertical_flip=True)

# datagen.fit(X_train)
In [53]:
# # Initialize and Build the Model
# #Clear any previous model from memory
# tf.keras.backend.clear_session()

# #Initialize model
# model5 = tf.keras.models.Sequential()

# #Add 1st Conv Layer
# model5.add(tf.keras.layers.Conv2D(64, kernel_size=(3, 3), input_shape=(128, 128, 3), activation='relu'))

# #Add 2nd Conv Layer
# model5.add(tf.keras.layers.Conv2D(64, kernel_size=(3,3), activation='relu'))

# #normalize data
# model5.add(tf.keras.layers.BatchNormalization())

# #Add Max Pool layer
# model5.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))

# #Add 3rd Conv Layer
# model5.add(tf.keras.layers.Conv2D(128, kernel_size=(3,3), activation='relu'))

# #normalize data
# model5.add(tf.keras.layers.BatchNormalization())

# #Add Max Pool layer
# model5.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))

# #Add 4th Conv Layer
# model5.add(tf.keras.layers.Conv2D(256, kernel_size=(3,3), activation='relu'))

# #normalize data
# model5.add(tf.keras.layers.BatchNormalization())

# #Add Max Pool layer
# model5.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))

# #Add Global Max Pool layer
# model5.add(tf.keras.layers.GlobalMaxPool2D())

# #Flatten the data
# model5.add(tf.keras.layers.Flatten())

# #Add 1st dense layer
# model5.add(tf.keras.layers.Dense(128, activation='relu'))

# #normalize data
# model5.add(tf.keras.layers.BatchNormalization())

# #Add Dropout
# model5.add(tf.keras.layers.Dropout(0.3))

# #Add 2nd dense layer
# model5.add(tf.keras.layers.Dense(128, activation='relu'))

# #normalize data
# model5.add(tf.keras.layers.BatchNormalization())

# #Add Dropout
# model5.add(tf.keras.layers.Dropout(0.3))

# #Add Output Layer
# model5.add(tf.keras.layers.Dense(12, activation='softmax'))
In [54]:
# # Compile the model
# # Specify Loss and Optimizer
# model5.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
In [55]:
# #Model Summary
# model5.summary()
In [56]:
# history5 = model5.fit_generator(datagen.flow(X_train, y_train, batch_size=200), 
#                     epochs=50, validation_data=(X_test, y_test), verbose = 2)
In [57]:
# #Plotting Train Loss vs Validation Loss
# plt.plot(history5.history['loss'])
# plt.plot(history5.history['val_loss'])
# plt.title('model loss')
# plt.ylabel('Loss')
# plt.xlabel('Epoch')
# plt.legend(['train', 'validation'], loc='upper left')
# plt.show()
In [58]:
# # Capturing learning history per epoch
# hist  = pd.DataFrame(history5.history)
# hist['epoch'] = history5.epoch

# # Plotting accuracy at different epochs
# plt.plot(hist['accuracy'])
# plt.plot(hist['val_accuracy'])
# plt.legend(("train" , "valid") , loc =0)

# # Printing results
# results = model5.evaluate(X_test, y_test)
In [59]:
# y_pred=model5.predict(X_test)
# y_pred
In [60]:
# # Classification Accuracy
# print("Classification Accuracy:")
# print('Loss and Accuracy on Training data:',model5.evaluate(X_train, y_train))
# print('Loss and Accuracy on Test data:',model5.evaluate(X_test, y_test))
# print()

# # Classification Report
# print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# # Confusion Matrix
# print("Confusion Matrix Chart:")
# cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
# df_cm = pd.DataFrame(cm, index = [i for i in [labels.classes_]],  
#                          columns = [i for i in [labels.classes_]])
# plt.figure(figsize = (12,10))
# sns.heatmap(df_cm, annot=True, fmt='g')
# plt.title('Confusion Matrix')
# plt.ylabel('Actual Label')
# plt.xlabel('Predicted Label')
# plt.show()

Part-B: Solution¶

  • DOMAIN: Botanical Research
  • CONTEXT: University X is currently undergoing some research involving understanding the characteristics of flowers. They already have invested on curating sample images. They require an automation which can create a classifier capable of determining a flower’s species from a photo.
  • DATA DESCRIPTION: The dataset comprises of images from 17 plant species.
  • PROJECT OBJECTIVE: To experiment with various approaches to train an image classifier to predict type of flower from the image.
In [1]:
# Import all the relevant libraries needed to complete the analysis, visualization, modeling and presentation
import pandas as pd
import numpy as np
import os

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
sns.set_style('darkgrid')
%matplotlib inline

from scipy import stats
from scipy.stats import zscore

from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import RobustScaler
from sklearn import model_selection
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold, KFold
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report 
from sklearn.metrics import ConfusionMatrixDisplay, precision_score, recall_score 
from sklearn.metrics import precision_recall_curve, roc_curve, auc, roc_auc_score
from sklearn.metrics import plot_precision_recall_curve, average_precision_score
from sklearn.metrics import f1_score, plot_roc_curve 

from imblearn.over_sampling import RandomOverSampler
from imblearn.over_sampling import SMOTENC, SMOTE, ADASYN
from imblearn.under_sampling import RandomUnderSampler

import cv2
from google.colab.patches import cv2_imshow
from glob import glob
import itertools

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam, RMSprop
from tensorflow.keras.layers import Dense, Dropout, Flatten, Activation, BatchNormalization
from tensorflow.keras.layers import Conv2D, MaxPool2D, GlobalMaxPool2D, GlobalAveragePooling2D
from tensorflow.keras import Input

from keras.utils.np_utils import to_categorical  
from keras.utils import np_utils
from tensorflow.keras.preprocessing.image import ImageDataGenerator

from tensorflow.keras.callbacks import Callback, EarlyStopping, ModelCheckpoint

import warnings
warnings.filterwarnings("ignore")

# pd.set_option('display.max_columns', None)
# pd.set_option('display.max_rows', None)
In [2]:
# Load the Drive helper and mount
from google.colab import drive

# This will prompt for authorization.
drive.mount('/content/drive')
Mounted at /content/drive

1. Import and Understand the data¶

1A. Import and read oxflower17 dataset from tflearn and split into X and Y while loading.¶

Hint: It can be imported from tflearn.datasets. If tflearn is not installed, install it. It can be loaded using: x, y = oxflower17.load_data()

In [3]:
pip install tflearn
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting tflearn
  Downloading tflearn-0.5.0.tar.gz (107 kB)
     |████████████████████████████████| 107 kB 7.5 MB/s 
Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from tflearn) (1.21.6)
Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from tflearn) (1.15.0)
Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (from tflearn) (7.1.2)
Building wheels for collected packages: tflearn
  Building wheel for tflearn (setup.py) ... done
  Created wheel for tflearn: filename=tflearn-0.5.0-py3-none-any.whl size=127299 sha256=e8ba893de888da7b09f742c340ef0cd22a224657e09156c9067e17a174732fb7
  Stored in directory: /root/.cache/pip/wheels/5f/14/2e/1d8e28cc47a5a931a2fb82438c9e37ef9246cc6a3774520271
Successfully built tflearn
Installing collected packages: tflearn
Successfully installed tflearn-0.5.0
In [4]:
import tflearn
import tflearn.datasets.oxflower17 as oxflower17

# Read the data
import tflearn.datasets.oxflower17 as oxflower17
X, y = oxflower17.load_data(one_hot=True, resize_pics=(128,128))
# X, y = oxflower17.load_data(resize_pics=(224,224))
# np.savez_compressed('oxflower17', X=X, Y=y)
WARNING:tensorflow:From /usr/local/lib/python3.7/dist-packages/tensorflow/python/compat/v2_compat.py:107: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
Downloading Oxford 17 category Flower Dataset, Please wait...
100.0% 60276736 / 60270631
Succesfully downloaded 17flowers.tgz 60270631 bytes.
File Extracted
Starting to parse images...
Parsing Done!

1B. Print Number of images and shape of the images.¶

In [5]:
print(X.shape)
print(y.shape)
(1360, 128, 128, 3)
(1360, 17)
In [6]:
X[0].min(), X[0].max()
Out[6]:
(0.0, 1.0)
In [7]:
X
Out[7]:
array([[[[0.6901961 , 0.69803923, 0.18039216],
         [0.6666667 , 0.654902  , 0.11372549],
         [0.6745098 , 0.627451  , 0.07058824],
         ...,
         [0.29411766, 0.29803923, 0.15294118],
         [0.4117647 , 0.39607844, 0.2       ],
         [0.48235294, 0.44313726, 0.22745098]],

        [[0.5294118 , 0.5254902 , 0.2784314 ],
         [0.65882355, 0.6666667 , 0.20392157],
         [0.6666667 , 0.65882355, 0.0627451 ],
         ...,
         [0.26666668, 0.2901961 , 0.14117648],
         [0.33333334, 0.3372549 , 0.13333334],
         [0.4117647 , 0.3882353 , 0.16862746]],

        [[0.38039216, 0.39215687, 0.32156864],
         [0.49411765, 0.52156866, 0.21960784],
         [0.64705884, 0.6784314 , 0.1882353 ],
         ...,
         [0.24313726, 0.29411766, 0.13333334],
         [0.35686275, 0.39607844, 0.18039216],
         [0.48235294, 0.49019608, 0.25882354]],

        ...,

        [[0.49411765, 0.52156866, 0.43529412],
         [0.6       , 0.6509804 , 0.5058824 ],
         [0.6156863 , 0.6784314 , 0.5411765 ],
         ...,
         [0.14117648, 0.17254902, 0.07058824],
         [0.1764706 , 0.20392157, 0.11372549],
         [0.18039216, 0.21568628, 0.10588235]],

        [[0.30980393, 0.30980393, 0.27450982],
         [0.5529412 , 0.57254905, 0.46666667],
         [0.6901961 , 0.72156864, 0.6156863 ],
         ...,
         [0.14117648, 0.1764706 , 0.08235294],
         [0.16470589, 0.19607843, 0.10588235],
         [0.18431373, 0.22352941, 0.10196079]],

        [[0.2784314 , 0.28235295, 0.27450982],
         [0.5372549 , 0.54901963, 0.45882353],
         [0.56078434, 0.5647059 , 0.45490196],
         ...,
         [0.16078432, 0.19215687, 0.10196079],
         [0.16470589, 0.19607843, 0.10588235],
         [0.18431373, 0.21960784, 0.09803922]]],


       [[[0.40392157, 0.49803922, 0.36078432],
         [0.42745098, 0.5294118 , 0.3764706 ],
         [0.3764706 , 0.49019608, 0.3137255 ],
         ...,
         [0.3137255 , 0.43529412, 0.21960784],
         [0.2627451 , 0.38431373, 0.16078432],
         [0.24705882, 0.3647059 , 0.15686275]],

        [[0.27058825, 0.34901962, 0.23529412],
         [0.2627451 , 0.3529412 , 0.21960784],
         [0.21176471, 0.3137255 , 0.15686275],
         ...,
         [0.35686275, 0.4745098 , 0.26666668],
         [0.3137255 , 0.43529412, 0.22352941],
         [0.29803923, 0.41568628, 0.20784314]],

        [[0.2627451 , 0.32941177, 0.23921569],
         [0.18431373, 0.25882354, 0.15294118],
         [0.05490196, 0.14117648, 0.01568628],
         ...,
         [0.34117648, 0.45490196, 0.2627451 ],
         [0.31764707, 0.43529412, 0.23529412],
         [0.30588236, 0.42352942, 0.21960784]],

        ...,

        [[0.15294118, 0.2509804 , 0.14901961],
         [0.16470589, 0.2627451 , 0.15294118],
         [0.21568628, 0.31764707, 0.2       ],
         ...,
         [0.37254903, 0.4745098 , 0.3764706 ],
         [0.38039216, 0.48235294, 0.38039216],
         [0.3647059 , 0.46666667, 0.36078432]],

        [[0.1254902 , 0.21176471, 0.13725491],
         [0.12941177, 0.21960784, 0.12941177],
         [0.15294118, 0.24313726, 0.13333334],
         ...,
         [0.39215687, 0.49411765, 0.40392157],
         [0.39607844, 0.49411765, 0.4       ],
         [0.3529412 , 0.45490196, 0.3529412 ]],

        [[0.15294118, 0.23529412, 0.16078432],
         [0.16078432, 0.24705882, 0.15686275],
         [0.14509805, 0.23529412, 0.1254902 ],
         ...,
         [0.43137255, 0.5372549 , 0.4392157 ],
         [0.41960785, 0.52156866, 0.42352942],
         [0.3647059 , 0.46666667, 0.37254903]]],


       [[[0.18431373, 0.18431373, 0.19607843],
         [0.30588236, 0.30588236, 0.31764707],
         [0.33333334, 0.33333334, 0.34509805],
         ...,
         [0.21960784, 0.20392157, 0.19215687],
         [0.2       , 0.18431373, 0.17254902],
         [0.18039216, 0.16862746, 0.15294118]],

        [[0.1254902 , 0.1254902 , 0.12941177],
         [0.1882353 , 0.1882353 , 0.19215687],
         [0.21960784, 0.21960784, 0.22352941],
         ...,
         [0.20784314, 0.19215687, 0.18039216],
         [0.18039216, 0.18039216, 0.16470589],
         [0.16078432, 0.16470589, 0.14509805]],

        [[0.09411765, 0.09411765, 0.09019608],
         [0.12156863, 0.12156863, 0.11764706],
         [0.13333334, 0.13333334, 0.12941177],
         ...,
         [0.19607843, 0.18039216, 0.16862746],
         [0.18431373, 0.18039216, 0.16078432],
         [0.16862746, 0.16470589, 0.14901961]],

        ...,

        [[0.19215687, 0.22352941, 0.0627451 ],
         [0.21960784, 0.2509804 , 0.09019608],
         [0.22745098, 0.25882354, 0.09803922],
         ...,
         [0.19607843, 0.23137255, 0.0627451 ],
         [0.19607843, 0.23137255, 0.05882353],
         [0.2       , 0.23529412, 0.05882353]],

        [[0.21568628, 0.24705882, 0.08627451],
         [0.21568628, 0.24705882, 0.08627451],
         [0.21960784, 0.2509804 , 0.09019608],
         ...,
         [0.1882353 , 0.22352941, 0.05490196],
         [0.1882353 , 0.22352941, 0.04705882],
         [0.19607843, 0.23137255, 0.05098039]],

        [[0.21568628, 0.24705882, 0.08627451],
         [0.21176471, 0.24313726, 0.08235294],
         [0.21568628, 0.24705882, 0.08627451],
         ...,
         [0.1882353 , 0.21960784, 0.06666667],
         [0.19215687, 0.22352941, 0.07058824],
         [0.19607843, 0.22745098, 0.07058824]]],


       ...,


       [[[0.30980393, 0.39607844, 0.10980392],
         [0.3647059 , 0.45882353, 0.16862746],
         [0.4       , 0.5176471 , 0.21960784],
         ...,
         [0.43529412, 0.53333336, 0.23921569],
         [0.4627451 , 0.5529412 , 0.24705882],
         [0.47843137, 0.5686275 , 0.2627451 ]],

        [[0.34901962, 0.4392157 , 0.15294118],
         [0.38431373, 0.4862745 , 0.19607843],
         [0.3647059 , 0.4862745 , 0.1882353 ],
         ...,
         [0.41960785, 0.5294118 , 0.22352941],
         [0.43137255, 0.53333336, 0.22352941],
         [0.4392157 , 0.5411765 , 0.23137255]],

        [[0.38039216, 0.47843137, 0.1882353 ],
         [0.38431373, 0.49803922, 0.20392157],
         [0.32156864, 0.45490196, 0.15294118],
         ...,
         [0.3764706 , 0.5058824 , 0.18431373],
         [0.40392157, 0.5254902 , 0.21176471],
         [0.43137255, 0.5529412 , 0.23529412]],

        ...,

        [[0.3137255 , 0.37254903, 0.15686275],
         [0.3647059 , 0.43137255, 0.21568628],
         [0.37254903, 0.44705883, 0.22745098],
         ...,
         [0.5764706 , 0.6745098 , 0.4392157 ],
         [0.56078434, 0.6666667 , 0.47058824],
         [0.54509807, 0.6509804 , 0.45882353]],

        [[0.36862746, 0.42745098, 0.21176471],
         [0.40392157, 0.46666667, 0.2509804 ],
         [0.37254903, 0.44705883, 0.22745098],
         ...,
         [0.5921569 , 0.69803923, 0.41960785],
         [0.54901963, 0.65882355, 0.41960785],
         [0.5411765 , 0.6509804 , 0.41568628]],

        [[0.41568628, 0.46666667, 0.24705882],
         [0.42352942, 0.48235294, 0.2627451 ],
         [0.36078432, 0.42745098, 0.21568628],
         ...,
         [0.5686275 , 0.6745098 , 0.4       ],
         [0.54509807, 0.654902  , 0.39607844],
         [0.54509807, 0.65882355, 0.40392157]]],


       [[[0.22745098, 0.3529412 , 0.18039216],
         [0.20392157, 0.31764707, 0.11764706],
         [0.18431373, 0.29411766, 0.02352941],
         ...,
         [0.03137255, 0.13725491, 0.03137255],
         [0.06666667, 0.16862746, 0.02745098],
         [0.16470589, 0.25490198, 0.12156863]],

        [[0.25882354, 0.36862746, 0.21960784],
         [0.19607843, 0.3019608 , 0.1254902 ],
         [0.17254902, 0.28627452, 0.03137255],
         ...,
         [0.06666667, 0.18039216, 0.03137255],
         [0.09411765, 0.20784314, 0.05882353],
         [0.1882353 , 0.29803923, 0.16470589]],

        [[0.2509804 , 0.33333334, 0.2       ],
         [0.16862746, 0.2627451 , 0.09411765],
         [0.15686275, 0.27450982, 0.02352941],
         ...,
         [0.15686275, 0.24313726, 0.08627451],
         [0.15686275, 0.2509804 , 0.1254902 ],
         [0.2       , 0.30980393, 0.18039216]],

        ...,

        [[0.34901962, 0.43137255, 0.31764707],
         [0.26666668, 0.34901962, 0.25490198],
         [0.21176471, 0.29411766, 0.22352941],
         ...,
         [0.36862746, 0.48235294, 0.18431373],
         [0.22745098, 0.38431373, 0.10588235],
         [0.61960787, 0.63529414, 0.14117648]],

        [[0.28235295, 0.35686275, 0.2509804 ],
         [0.22352941, 0.29803923, 0.21176471],
         [0.22745098, 0.29411766, 0.23137255],
         ...,
         [0.4627451 , 0.47843137, 0.14901961],
         [0.42745098, 0.50980395, 0.17254902],
         [0.77254903, 0.7529412 , 0.15294118]],

        [[0.23529412, 0.32156864, 0.20392157],
         [0.21176471, 0.29411766, 0.21176471],
         [0.2509804 , 0.29411766, 0.21568628],
         ...,
         [0.48235294, 0.44313726, 0.1254902 ],
         [0.47843137, 0.47843137, 0.12156863],
         [0.84705883, 0.7921569 , 0.09019608]]],


       [[[0.23137255, 0.10588235, 0.09411765],
         [0.23137255, 0.08235294, 0.01176471],
         [0.29411766, 0.13725491, 0.00784314],
         ...,
         [0.31764707, 0.25882354, 0.12156863],
         [0.15294118, 0.09411765, 0.01960784],
         [0.10980392, 0.03529412, 0.01176471]],

        [[0.25882354, 0.15294118, 0.07843138],
         [0.2       , 0.0627451 , 0.        ],
         [0.25882354, 0.10196079, 0.01568628],
         ...,
         [0.12941177, 0.10196079, 0.03137255],
         [0.08627451, 0.05490196, 0.02352941],
         [0.05490196, 0.01960784, 0.00784314]],

        [[0.2627451 , 0.18039216, 0.04313726],
         [0.2       , 0.07058824, 0.00392157],
         [0.21176471, 0.05882353, 0.01960784],
         ...,
         [0.04705882, 0.05882353, 0.01960784],
         [0.02745098, 0.03137255, 0.01176471],
         [0.        , 0.        , 0.        ]],

        ...,

        [[0.01176471, 0.00784314, 0.02745098],
         [0.03921569, 0.03529412, 0.        ],
         [0.0627451 , 0.02745098, 0.03137255],
         ...,
         [0.11372549, 0.02745098, 0.00784314],
         [0.14509805, 0.06666667, 0.05098039],
         [0.08235294, 0.01176471, 0.01568628]],

        [[0.01960784, 0.00392157, 0.04705882],
         [0.02745098, 0.00392157, 0.        ],
         [0.04705882, 0.        , 0.03137255],
         ...,
         [0.09411765, 0.02352941, 0.01176471],
         [0.08235294, 0.02352941, 0.00784314],
         [0.05882353, 0.00392157, 0.00392157]],

        [[0.03137255, 0.        , 0.05882353],
         [0.04313726, 0.01176471, 0.00784314],
         [0.05882353, 0.00784314, 0.05490196],
         ...,
         [0.10588235, 0.0627451 , 0.05490196],
         [0.05098039, 0.01960784, 0.01176471],
         [0.01568628, 0.00784314, 0.        ]]]], dtype=float32)

1C. Print count of each class from y.¶

In [8]:
# One-hot-encoded numpy array
y
Out[8]:
array([[1., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 1., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.]])
In [9]:
# No of Unique rows in y
np.unique(y, axis=0)
Out[9]:
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        1.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.],
       [1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0.]])
In [10]:
# Converting y into a dataframe
ydf = pd.DataFrame(y, columns = [i for i in range(0,17)])
print(ydf)
print(type(ydf))
       0    1    2    3    4    5    6    7    8    9    10   11   12   13  \
0     1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
1     0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
2     0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0   
3     1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
4     0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
...   ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...   
1355  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0   
1356  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
1357  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
1358  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   
1359  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0   

       14   15   16  
0     0.0  0.0  0.0  
1     0.0  0.0  0.0  
2     0.0  0.0  0.0  
3     0.0  0.0  0.0  
4     0.0  0.0  0.0  
...   ...  ...  ...  
1355  0.0  0.0  0.0  
1356  0.0  0.0  0.0  
1357  0.0  1.0  0.0  
1358  0.0  0.0  0.0  
1359  0.0  0.0  0.0  

[1360 rows x 17 columns]
<class 'pandas.core.frame.DataFrame'>
In [11]:
# Reverse one-hot-encoding in pandas
ydf.idxmax(axis=1)
Out[11]:
0        0
1        5
2        7
3        0
4        2
        ..
1355    12
1356     2
1357    15
1358     4
1359     2
Length: 1360, dtype: int64
In [12]:
# Number of images in each class
ydf.idxmax(axis=1).value_counts()
Out[12]:
0     80
14    80
10    80
15    80
11    80
9     80
8     80
6     80
3     80
5     80
13    80
4     80
12    80
16    80
2     80
7     80
1     80
dtype: int64

Looks like the data is well balanced; Good for model building.

2. Image Exploration & Transformation¶

[Learning purpose - Not related to final model]

In [13]:
# y as numpy array with numeric labels
y1 = ydf.idxmax(axis=1).to_numpy()
y1
Out[13]:
array([ 0,  5,  7, ..., 15,  4,  2])

2A. Display 5 random images¶

In [14]:
# Visualize the images along with their labels
def show_img(count, data, label):
  
    fig, axs = plt.subplots(1, count, figsize=(20, 16))
    for i in range(0, count):
        axs[i].imshow(data[i], label=label[i])
        axs[i].set_title('Label: {}'.format(label[i]))
    plt.show()
        
show_img(5, X, y1)
No description has been provided for this image
In [15]:
# Displaying an image from each class (Total classes = 17 with labels from 0 to 16)
cols = 5
rows = int(np.ceil(len(np.unique(y1))/cols))

fig, ax = plt.subplots(rows, cols, figsize=(20,20))
for i in np.unique(y1):
  col = i % 5
  row = int(i/5)

  ax[row][col].imshow(X[i])
  ax[row][col].tick_params(top=False, bottom=False, left=False, right=False, labelleft=False, labelbottom=False)
  ax[row][col].set_title(f"Flower Label: {i}",{'fontsize':15})
plt.show() 
No description has been provided for this image

2B. Select any image from the dataset and assign it to a variable.¶

In [16]:
# Selecting an image from the dataset
path = '/content/17flowers/jpg/9/image_0721.jpg'

# Using the cv2_imshow
from google.colab.patches import cv2_imshow
img1 = cv2.imread(path, cv2.IMREAD_COLOR)
# cv2_imshow(img1)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Using the imshow
plt.figure(figsize=(20, 10))
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
plt.imshow(img1)
Out[16]:
<matplotlib.image.AxesImage at 0x7f2fd0910c10>
No description has been provided for this image

2C. Transform the image into grayscale format and display the same.¶

In [17]:
img2 = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
# cv2_imshow(img2)

# Using the imshow
plt.figure(figsize=(20, 10))
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
plt.imshow(img2)
Out[17]:
<matplotlib.image.AxesImage at 0x7f2fd00e0dd0>
No description has been provided for this image

2D. Apply a filter to sharpen the image and display the image before and after sharpening.¶

In [18]:
# # Original Image
# img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)

# Sharpened Image
img3 = cv2.imread(path, cv2.IMREAD_COLOR)

kernel1 = np.array([[0, -1, 0],
                   [-1, 5,-1],
                   [0, -1, 0]])
img3 = cv2.filter2D(src=img3, ddepth=-1, kernel=kernel1)
img3 = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB)
# cv2_imshow(img1)
# cv2_imshow(img3)

fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(1, 2, 1)
imgplot = plt.imshow(img1)
ax.set_title('Original Image')

ax = fig.add_subplot(1, 2, 2)
imgplot = plt.imshow(img3)
ax.set_title('Sharpened Image')
Out[18]:
Text(0.5, 1.0, 'Sharpened Image')
No description has been provided for this image

2E. Apply a filter to blur the image and display the image before and after blur.¶

In [19]:
# # Original Image
# img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)

# Sharpened Image
img4 = cv2.imread(path, cv2.IMREAD_COLOR)

img4 = cv2.blur(src=img4, ksize=(6,6))
img4 = cv2.cvtColor(img4, cv2.COLOR_BGR2RGB)
# cv2_imshow(img1)
# cv2_imshow(img4)

fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(1, 2, 1)
imgplot = plt.imshow(img1)
ax.set_title('Original Image')

ax = fig.add_subplot(1, 2, 2)
imgplot = plt.imshow(img4)
ax.set_title('Blurred Image')
Out[19]:
Text(0.5, 1.0, 'Blurred Image')
No description has been provided for this image

2F. Display all the 4 images from above questions besides each other to observe the difference.¶

In [20]:
# Original Image and Sharpened Image
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(1, 2, 1)
imgplot = plt.imshow(img1)
ax.set_title('Original Image')

ax = fig.add_subplot(1, 2, 2)
imgplot = plt.imshow(img3)
ax.set_title('Sharpened Image')

# Original Image and Blurred Image
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(1, 2, 1)
imgplot = plt.imshow(img1)
ax.set_title('Original Image')

ax = fig.add_subplot(1, 2, 2)
imgplot = plt.imshow(img4)
ax.set_title('Blurred Image')
Out[20]:
Text(0.5, 1.0, 'Blurred Image')
No description has been provided for this image
No description has been provided for this image

3. Model training and Tuning:¶

Due to time constraint, I am using small number of epochs, and training only the selected models. Similar process can be replicated for other complex models (Model-4 and Model-5).

3A. Split the data into train and test with 80:20 proportion.¶

In [21]:
# Reshaping the data to train using the SVM
print(X.shape)
print(y.shape)
(1360, 128, 128, 3)
(1360, 17)
In [22]:
X1 = X.reshape(X.shape[0], 128 * 128 *3)
X1.shape
Out[22]:
(1360, 49152)
In [23]:
y1
Out[23]:
array([ 0,  5,  7, ..., 15,  4,  2])
In [24]:
y1[1]
Out[24]:
5
In [25]:
y1.shape
Out[25]:
(1360,)
In [26]:
# Split the data for training and testing
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X1, y1, test_size=0.2, random_state=0)
In [27]:
print(X_train.shape,X_test.shape)
print(y_train.shape,y_test.shape)
(1088, 49152) (272, 49152)
(1088,) (272,)

3B. Train a model using any Supervised Learning algorithm and share performance metrics on test data.¶

In [28]:
# Using SVM from SkLearn
from sklearn.svm import SVC
In [29]:
#Create svm_model Object
model1 = SVC()

#Training the model
model1.fit(X_train, y_train)

#Predict testing set
y_pred = model1.predict(X_test)
In [30]:
# Classification Accuracy
print("Classification Accuracy:")
print('Accuracy on Training data:',model1.score(X_train, y_train))
print('Accuracy on Test data:',model1.score(X_test, y_test))
print()

# Classification Report
print("Classification Report:\n",classification_report(y_test, y_pred))

# Confusion Matrix
print("Confusion Matrix Chart:")
cm = confusion_matrix(y_test, y_pred)
df_cm = pd.DataFrame(cm, index = [i for i in ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16']],  
                         columns = [i for i in ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16']])
plt.figure(figsize = (12,10))
sns.heatmap(df_cm, annot=True, fmt='g')
plt.title('Confusion Matrix')
plt.ylabel('Actual Label')
plt.xlabel('Predicted Label')
plt.show()
Classification Accuracy:
Accuracy on Training data: 0.9200367647058824
Accuracy on Test data: 0.49264705882352944

Classification Report:
               precision    recall  f1-score   support

           0       0.40      0.71      0.51        14
           1       0.37      0.41      0.39        17
           2       0.64      0.60      0.62        15
           3       0.40      0.33      0.36        12
           4       0.59      0.62      0.61        16
           5       0.28      0.53      0.36        15
           6       0.42      0.36      0.38        14
           7       0.50      0.62      0.55        13
           8       0.88      0.44      0.58        16
           9       0.50      0.44      0.47        18
          10       0.37      0.35      0.36        20
          11       0.26      0.50      0.34        12
          12       0.76      0.65      0.70        20
          13       0.70      0.41      0.52        17
          14       0.33      0.14      0.20        21
          15       0.57      0.53      0.55        15
          16       1.00      0.82      0.90        17

    accuracy                           0.49       272
   macro avg       0.53      0.50      0.50       272
weighted avg       0.53      0.49      0.50       272

Confusion Matrix Chart:
No description has been provided for this image

Evaluation metrics allow us to estimate errors to determine how well our models are performing:

Accuracy: ratio of correct predictions over total predictions.

Precision: how often the classifier is correct when it predicts positive.

Recall: how often the classifier is correct for all positive instances.

F-Score: single measurement to combine precision and recall.

Considering the Class Recall, Precision, F1 Score and Accuracy as the most important parameters to decide the best model for this problem. We have the highest values in Model-3. Please refer the Model-3 for the same. (Part 3D)

3C. Train a model using Neural Network and share performance metrics on test data.¶

In [31]:
# Split the data for training and testing
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X1, y, test_size=0.2, random_state=0)
In [32]:
print(X_train.shape,X_test.shape)
print(y_train.shape,y_test.shape)
(1088, 49152) (272, 49152)
(1088, 17) (272, 17)
In [33]:
model2 = Sequential()

model2.add(BatchNormalization())
model2.add(Dense(256,activation='relu',kernel_initializer='he_uniform',input_dim = X_train.shape[1]))
model2.add(Dropout(0.4))

model2.add(BatchNormalization())
model2.add(Dense(128,activation='relu',kernel_initializer='he_uniform'))
model2.add(Dropout(0.4))

model2.add(BatchNormalization())
model2.add(Dense(64,activation='relu',kernel_initializer='he_uniform'))
model2.add(Dropout(0.4))

model2.add(BatchNormalization())
model2.add(Dense(32,activation='relu',kernel_initializer='he_uniform'))
model2.add(Dropout(0.4))

model2.add(Dense(y_train.shape[1], activation = 'sigmoid'))

# Compiling the ANN with Adam optimizer and binary cross entropy loss function 
optimizer = tf.keras.optimizers.Adam(0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
model2.compile(loss='categorical_crossentropy',optimizer=optimizer,metrics=['accuracy'])
In [34]:
# Looking into our base model2
model2.build(X_train.shape)
model2.summary()
WARNING:tensorflow:From /usr/local/lib/python3.7/dist-packages/keras/layers/normalization/batch_normalization.py:514: _colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 batch_normalization (BatchN  multiple                 196608    
 ormalization)                                                   
                                                                 
 dense (Dense)               multiple                  12583168  
                                                                 
 dropout (Dropout)           multiple                  0         
                                                                 
 batch_normalization_1 (Batc  multiple                 1024      
 hNormalization)                                                 
                                                                 
 dense_1 (Dense)             multiple                  32896     
                                                                 
 dropout_1 (Dropout)         multiple                  0         
                                                                 
 batch_normalization_2 (Batc  multiple                 512       
 hNormalization)                                                 
                                                                 
 dense_2 (Dense)             multiple                  8256      
                                                                 
 dropout_2 (Dropout)         multiple                  0         
                                                                 
 batch_normalization_3 (Batc  multiple                 256       
 hNormalization)                                                 
                                                                 
 dense_3 (Dense)             multiple                  2080      
                                                                 
 dropout_3 (Dropout)         multiple                  0         
                                                                 
 dense_4 (Dense)             multiple                  561       
                                                                 
=================================================================
Total params: 12,825,361
Trainable params: 12,726,161
Non-trainable params: 99,200
_________________________________________________________________
In [35]:
# Fit the model2
history2=model2.fit(X_train, y_train, validation_data=(X_test,y_test), epochs=200, batch_size=200, verbose=2, shuffle=True)
Train on 1088 samples, validate on 272 samples
Epoch 1/200
1088/1088 - 5s - loss: 3.5290 - acc: 0.0662 - val_loss: 6.4445 - val_acc: 0.0699 - 5s/epoch - 5ms/sample
Epoch 2/200
1088/1088 - 4s - loss: 3.2801 - acc: 0.0772 - val_loss: 4.0881 - val_acc: 0.0956 - 4s/epoch - 4ms/sample
Epoch 3/200
1088/1088 - 4s - loss: 3.1104 - acc: 0.1066 - val_loss: 3.3113 - val_acc: 0.1176 - 4s/epoch - 4ms/sample
Epoch 4/200
1088/1088 - 4s - loss: 3.0335 - acc: 0.0974 - val_loss: 2.9747 - val_acc: 0.1618 - 4s/epoch - 4ms/sample
Epoch 5/200
1088/1088 - 4s - loss: 2.9799 - acc: 0.1029 - val_loss: 2.7804 - val_acc: 0.1728 - 4s/epoch - 4ms/sample
Epoch 6/200
1088/1088 - 5s - loss: 2.9089 - acc: 0.1268 - val_loss: 2.6525 - val_acc: 0.2059 - 5s/epoch - 5ms/sample
Epoch 7/200
1088/1088 - 4s - loss: 2.7700 - acc: 0.1452 - val_loss: 2.5820 - val_acc: 0.2059 - 4s/epoch - 4ms/sample
Epoch 8/200
1088/1088 - 4s - loss: 2.8462 - acc: 0.1425 - val_loss: 2.5470 - val_acc: 0.2059 - 4s/epoch - 4ms/sample
Epoch 9/200
1088/1088 - 4s - loss: 2.6936 - acc: 0.1590 - val_loss: 2.5200 - val_acc: 0.2059 - 4s/epoch - 4ms/sample
Epoch 10/200
1088/1088 - 4s - loss: 2.7143 - acc: 0.1627 - val_loss: 2.5006 - val_acc: 0.2132 - 4s/epoch - 4ms/sample
Epoch 11/200
1088/1088 - 4s - loss: 2.6043 - acc: 0.1829 - val_loss: 2.4784 - val_acc: 0.2059 - 4s/epoch - 4ms/sample
Epoch 12/200
1088/1088 - 4s - loss: 2.6592 - acc: 0.1719 - val_loss: 2.4529 - val_acc: 0.2206 - 4s/epoch - 4ms/sample
Epoch 13/200
1088/1088 - 4s - loss: 2.5611 - acc: 0.1884 - val_loss: 2.4267 - val_acc: 0.2243 - 4s/epoch - 4ms/sample
Epoch 14/200
1088/1088 - 4s - loss: 2.5246 - acc: 0.1921 - val_loss: 2.3918 - val_acc: 0.2206 - 4s/epoch - 3ms/sample
Epoch 15/200
1088/1088 - 4s - loss: 2.5345 - acc: 0.1847 - val_loss: 2.3658 - val_acc: 0.2353 - 4s/epoch - 4ms/sample
Epoch 16/200
1088/1088 - 4s - loss: 2.4977 - acc: 0.1820 - val_loss: 2.3430 - val_acc: 0.2426 - 4s/epoch - 4ms/sample
Epoch 17/200
1088/1088 - 4s - loss: 2.4030 - acc: 0.2040 - val_loss: 2.3204 - val_acc: 0.2647 - 4s/epoch - 4ms/sample
Epoch 18/200
1088/1088 - 4s - loss: 2.4083 - acc: 0.2197 - val_loss: 2.3068 - val_acc: 0.2610 - 4s/epoch - 3ms/sample
Epoch 19/200
1088/1088 - 4s - loss: 2.3677 - acc: 0.2132 - val_loss: 2.2935 - val_acc: 0.2647 - 4s/epoch - 3ms/sample
Epoch 20/200
1088/1088 - 3s - loss: 2.3819 - acc: 0.1985 - val_loss: 2.2754 - val_acc: 0.2831 - 3s/epoch - 3ms/sample
Epoch 21/200
1088/1088 - 4s - loss: 2.3319 - acc: 0.2316 - val_loss: 2.2490 - val_acc: 0.2904 - 4s/epoch - 4ms/sample
Epoch 22/200
1088/1088 - 4s - loss: 2.3505 - acc: 0.2188 - val_loss: 2.2276 - val_acc: 0.2868 - 4s/epoch - 4ms/sample
Epoch 23/200
1088/1088 - 4s - loss: 2.2965 - acc: 0.2482 - val_loss: 2.2080 - val_acc: 0.2978 - 4s/epoch - 4ms/sample
Epoch 24/200
1088/1088 - 4s - loss: 2.2124 - acc: 0.2665 - val_loss: 2.1820 - val_acc: 0.3051 - 4s/epoch - 4ms/sample
Epoch 25/200
1088/1088 - 3s - loss: 2.2190 - acc: 0.2886 - val_loss: 2.1572 - val_acc: 0.3199 - 3s/epoch - 3ms/sample
Epoch 26/200
1088/1088 - 3s - loss: 2.1817 - acc: 0.2656 - val_loss: 2.1397 - val_acc: 0.3382 - 3s/epoch - 3ms/sample
Epoch 27/200
1088/1088 - 4s - loss: 2.1738 - acc: 0.2748 - val_loss: 2.1191 - val_acc: 0.3456 - 4s/epoch - 4ms/sample
Epoch 28/200
1088/1088 - 4s - loss: 2.1231 - acc: 0.2923 - val_loss: 2.0905 - val_acc: 0.3603 - 4s/epoch - 4ms/sample
Epoch 29/200
1088/1088 - 5s - loss: 2.1329 - acc: 0.2730 - val_loss: 2.0610 - val_acc: 0.3529 - 5s/epoch - 5ms/sample
Epoch 30/200
1088/1088 - 4s - loss: 2.1058 - acc: 0.2767 - val_loss: 2.0332 - val_acc: 0.3640 - 4s/epoch - 4ms/sample
Epoch 31/200
1088/1088 - 4s - loss: 2.0429 - acc: 0.3097 - val_loss: 2.0111 - val_acc: 0.3713 - 4s/epoch - 4ms/sample
Epoch 32/200
1088/1088 - 4s - loss: 2.0629 - acc: 0.3116 - val_loss: 1.9924 - val_acc: 0.3787 - 4s/epoch - 4ms/sample
Epoch 33/200
1088/1088 - 4s - loss: 2.0359 - acc: 0.2960 - val_loss: 1.9809 - val_acc: 0.3566 - 4s/epoch - 3ms/sample
Epoch 34/200
1088/1088 - 3s - loss: 1.9756 - acc: 0.3281 - val_loss: 1.9736 - val_acc: 0.3603 - 3s/epoch - 3ms/sample
Epoch 35/200
1088/1088 - 4s - loss: 1.9471 - acc: 0.3254 - val_loss: 1.9500 - val_acc: 0.3750 - 4s/epoch - 4ms/sample
Epoch 36/200
1088/1088 - 4s - loss: 1.9095 - acc: 0.3281 - val_loss: 1.9226 - val_acc: 0.3897 - 4s/epoch - 4ms/sample
Epoch 37/200
1088/1088 - 4s - loss: 1.8909 - acc: 0.3300 - val_loss: 1.9032 - val_acc: 0.4154 - 4s/epoch - 4ms/sample
Epoch 38/200
1088/1088 - 4s - loss: 1.8530 - acc: 0.3649 - val_loss: 1.8913 - val_acc: 0.4154 - 4s/epoch - 4ms/sample
Epoch 39/200
1088/1088 - 4s - loss: 1.8380 - acc: 0.3631 - val_loss: 1.8867 - val_acc: 0.4228 - 4s/epoch - 4ms/sample
Epoch 40/200
1088/1088 - 4s - loss: 1.8365 - acc: 0.3621 - val_loss: 1.8694 - val_acc: 0.4154 - 4s/epoch - 4ms/sample
Epoch 41/200
1088/1088 - 4s - loss: 1.7934 - acc: 0.3741 - val_loss: 1.8572 - val_acc: 0.4118 - 4s/epoch - 3ms/sample
Epoch 42/200
1088/1088 - 5s - loss: 1.7393 - acc: 0.3989 - val_loss: 1.8404 - val_acc: 0.4228 - 5s/epoch - 5ms/sample
Epoch 43/200
1088/1088 - 4s - loss: 1.7237 - acc: 0.4072 - val_loss: 1.8157 - val_acc: 0.4081 - 4s/epoch - 4ms/sample
Epoch 44/200
1088/1088 - 4s - loss: 1.7012 - acc: 0.3961 - val_loss: 1.7949 - val_acc: 0.4154 - 4s/epoch - 3ms/sample
Epoch 45/200
1088/1088 - 4s - loss: 1.6461 - acc: 0.4320 - val_loss: 1.7771 - val_acc: 0.4338 - 4s/epoch - 3ms/sample
Epoch 46/200
1088/1088 - 4s - loss: 1.6952 - acc: 0.3989 - val_loss: 1.7625 - val_acc: 0.4338 - 4s/epoch - 3ms/sample
Epoch 47/200
1088/1088 - 4s - loss: 1.6472 - acc: 0.4136 - val_loss: 1.7488 - val_acc: 0.4375 - 4s/epoch - 3ms/sample
Epoch 48/200
1088/1088 - 4s - loss: 1.5815 - acc: 0.4688 - val_loss: 1.7249 - val_acc: 0.4522 - 4s/epoch - 3ms/sample
Epoch 49/200
1088/1088 - 4s - loss: 1.5735 - acc: 0.4540 - val_loss: 1.7101 - val_acc: 0.4412 - 4s/epoch - 4ms/sample
Epoch 50/200
1088/1088 - 4s - loss: 1.5749 - acc: 0.4375 - val_loss: 1.7127 - val_acc: 0.4338 - 4s/epoch - 3ms/sample
Epoch 51/200
1088/1088 - 4s - loss: 1.5477 - acc: 0.4614 - val_loss: 1.6917 - val_acc: 0.4375 - 4s/epoch - 4ms/sample
Epoch 52/200
1088/1088 - 4s - loss: 1.4931 - acc: 0.4798 - val_loss: 1.6936 - val_acc: 0.4522 - 4s/epoch - 4ms/sample
Epoch 53/200
1088/1088 - 4s - loss: 1.4664 - acc: 0.5018 - val_loss: 1.7160 - val_acc: 0.4449 - 4s/epoch - 3ms/sample
Epoch 54/200
1088/1088 - 4s - loss: 1.4883 - acc: 0.4954 - val_loss: 1.7093 - val_acc: 0.4449 - 4s/epoch - 3ms/sample
Epoch 55/200
1088/1088 - 4s - loss: 1.4343 - acc: 0.4917 - val_loss: 1.6910 - val_acc: 0.4522 - 4s/epoch - 4ms/sample
Epoch 56/200
1088/1088 - 4s - loss: 1.4192 - acc: 0.4835 - val_loss: 1.6817 - val_acc: 0.4596 - 4s/epoch - 4ms/sample
Epoch 57/200
1088/1088 - 4s - loss: 1.3875 - acc: 0.5349 - val_loss: 1.6803 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 58/200
1088/1088 - 4s - loss: 1.3713 - acc: 0.5138 - val_loss: 1.6818 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 59/200
1088/1088 - 4s - loss: 1.3709 - acc: 0.5331 - val_loss: 1.6633 - val_acc: 0.4779 - 4s/epoch - 3ms/sample
Epoch 60/200
1088/1088 - 4s - loss: 1.3148 - acc: 0.5414 - val_loss: 1.6473 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 61/200
1088/1088 - 4s - loss: 1.2994 - acc: 0.5395 - val_loss: 1.6555 - val_acc: 0.4632 - 4s/epoch - 3ms/sample
Epoch 62/200
1088/1088 - 4s - loss: 1.2891 - acc: 0.5478 - val_loss: 1.6675 - val_acc: 0.4522 - 4s/epoch - 3ms/sample
Epoch 63/200
1088/1088 - 4s - loss: 1.2450 - acc: 0.5744 - val_loss: 1.6702 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 64/200
1088/1088 - 4s - loss: 1.2493 - acc: 0.5689 - val_loss: 1.6715 - val_acc: 0.4449 - 4s/epoch - 3ms/sample
Epoch 65/200
1088/1088 - 4s - loss: 1.2985 - acc: 0.5515 - val_loss: 1.6708 - val_acc: 0.4706 - 4s/epoch - 3ms/sample
Epoch 66/200
1088/1088 - 4s - loss: 1.1802 - acc: 0.6011 - val_loss: 1.6484 - val_acc: 0.4743 - 4s/epoch - 4ms/sample
Epoch 67/200
1088/1088 - 4s - loss: 1.2023 - acc: 0.5790 - val_loss: 1.6483 - val_acc: 0.4816 - 4s/epoch - 4ms/sample
Epoch 68/200
1088/1088 - 4s - loss: 1.1612 - acc: 0.6029 - val_loss: 1.6699 - val_acc: 0.4853 - 4s/epoch - 4ms/sample
Epoch 69/200
1088/1088 - 4s - loss: 1.1296 - acc: 0.6048 - val_loss: 1.6436 - val_acc: 0.4926 - 4s/epoch - 3ms/sample
Epoch 70/200
1088/1088 - 4s - loss: 1.1097 - acc: 0.6213 - val_loss: 1.6394 - val_acc: 0.5000 - 4s/epoch - 4ms/sample
Epoch 71/200
1088/1088 - 4s - loss: 1.1118 - acc: 0.6149 - val_loss: 1.6040 - val_acc: 0.5037 - 4s/epoch - 3ms/sample
Epoch 72/200
1088/1088 - 4s - loss: 1.0908 - acc: 0.6167 - val_loss: 1.6378 - val_acc: 0.4559 - 4s/epoch - 3ms/sample
Epoch 73/200
1088/1088 - 4s - loss: 1.0429 - acc: 0.6434 - val_loss: 1.6555 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 74/200
1088/1088 - 3s - loss: 1.0195 - acc: 0.6535 - val_loss: 1.6518 - val_acc: 0.4743 - 3s/epoch - 3ms/sample
Epoch 75/200
1088/1088 - 4s - loss: 1.0621 - acc: 0.6121 - val_loss: 1.6660 - val_acc: 0.4853 - 4s/epoch - 4ms/sample
Epoch 76/200
1088/1088 - 4s - loss: 1.0034 - acc: 0.6719 - val_loss: 1.6871 - val_acc: 0.4816 - 4s/epoch - 3ms/sample
Epoch 77/200
1088/1088 - 4s - loss: 1.0089 - acc: 0.6296 - val_loss: 1.6660 - val_acc: 0.4963 - 4s/epoch - 3ms/sample
Epoch 78/200
1088/1088 - 4s - loss: 1.0028 - acc: 0.6618 - val_loss: 1.6844 - val_acc: 0.4779 - 4s/epoch - 4ms/sample
Epoch 79/200
1088/1088 - 6s - loss: 0.9763 - acc: 0.6728 - val_loss: 1.6351 - val_acc: 0.4743 - 6s/epoch - 5ms/sample
Epoch 80/200
1088/1088 - 4s - loss: 0.9811 - acc: 0.6489 - val_loss: 1.6175 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 81/200
1088/1088 - 4s - loss: 0.9717 - acc: 0.6682 - val_loss: 1.6550 - val_acc: 0.4485 - 4s/epoch - 4ms/sample
Epoch 82/200
1088/1088 - 4s - loss: 0.9119 - acc: 0.6792 - val_loss: 1.6515 - val_acc: 0.4375 - 4s/epoch - 4ms/sample
Epoch 83/200
1088/1088 - 4s - loss: 0.9167 - acc: 0.6765 - val_loss: 1.6608 - val_acc: 0.4449 - 4s/epoch - 3ms/sample
Epoch 84/200
1088/1088 - 4s - loss: 0.9606 - acc: 0.7040 - val_loss: 1.7058 - val_acc: 0.4449 - 4s/epoch - 3ms/sample
Epoch 85/200
1088/1088 - 4s - loss: 0.9296 - acc: 0.6847 - val_loss: 1.7440 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 86/200
1088/1088 - 4s - loss: 0.9299 - acc: 0.6884 - val_loss: 1.8221 - val_acc: 0.4706 - 4s/epoch - 3ms/sample
Epoch 87/200
1088/1088 - 4s - loss: 0.8798 - acc: 0.7004 - val_loss: 1.8113 - val_acc: 0.4522 - 4s/epoch - 4ms/sample
Epoch 88/200
1088/1088 - 4s - loss: 0.8799 - acc: 0.7013 - val_loss: 1.7746 - val_acc: 0.4669 - 4s/epoch - 4ms/sample
Epoch 89/200
1088/1088 - 4s - loss: 0.8460 - acc: 0.6994 - val_loss: 1.7558 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 90/200
1088/1088 - 4s - loss: 0.8493 - acc: 0.7059 - val_loss: 1.7532 - val_acc: 0.4890 - 4s/epoch - 4ms/sample
Epoch 91/200
1088/1088 - 4s - loss: 0.8578 - acc: 0.7059 - val_loss: 1.7667 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 92/200
1088/1088 - 4s - loss: 0.8221 - acc: 0.7169 - val_loss: 1.7571 - val_acc: 0.4816 - 4s/epoch - 3ms/sample
Epoch 93/200
1088/1088 - 4s - loss: 0.8094 - acc: 0.7307 - val_loss: 1.7463 - val_acc: 0.4853 - 4s/epoch - 3ms/sample
Epoch 94/200
1088/1088 - 4s - loss: 0.8045 - acc: 0.7105 - val_loss: 1.7464 - val_acc: 0.4779 - 4s/epoch - 4ms/sample
Epoch 95/200
1088/1088 - 4s - loss: 0.7833 - acc: 0.7123 - val_loss: 1.7866 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 96/200
1088/1088 - 4s - loss: 0.7650 - acc: 0.7344 - val_loss: 1.7928 - val_acc: 0.4779 - 4s/epoch - 4ms/sample
Epoch 97/200
1088/1088 - 4s - loss: 0.7585 - acc: 0.7178 - val_loss: 1.7659 - val_acc: 0.4853 - 4s/epoch - 4ms/sample
Epoch 98/200
1088/1088 - 4s - loss: 0.7744 - acc: 0.7408 - val_loss: 1.7975 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 99/200
1088/1088 - 4s - loss: 0.7227 - acc: 0.7482 - val_loss: 1.7694 - val_acc: 0.4853 - 4s/epoch - 4ms/sample
Epoch 100/200
1088/1088 - 4s - loss: 0.7072 - acc: 0.7721 - val_loss: 1.7849 - val_acc: 0.4816 - 4s/epoch - 4ms/sample
Epoch 101/200
1088/1088 - 3s - loss: 0.7497 - acc: 0.7509 - val_loss: 1.7754 - val_acc: 0.4926 - 3s/epoch - 3ms/sample
Epoch 102/200
1088/1088 - 4s - loss: 0.6943 - acc: 0.7748 - val_loss: 1.8395 - val_acc: 0.4890 - 4s/epoch - 4ms/sample
Epoch 103/200
1088/1088 - 4s - loss: 0.6577 - acc: 0.7886 - val_loss: 1.8308 - val_acc: 0.4963 - 4s/epoch - 4ms/sample
Epoch 104/200
1088/1088 - 4s - loss: 0.6908 - acc: 0.7583 - val_loss: 1.8435 - val_acc: 0.4890 - 4s/epoch - 3ms/sample
Epoch 105/200
1088/1088 - 4s - loss: 0.7232 - acc: 0.7454 - val_loss: 1.8108 - val_acc: 0.4963 - 4s/epoch - 4ms/sample
Epoch 106/200
1088/1088 - 4s - loss: 0.7062 - acc: 0.7482 - val_loss: 1.8442 - val_acc: 0.5000 - 4s/epoch - 3ms/sample
Epoch 107/200
1088/1088 - 4s - loss: 0.6178 - acc: 0.7858 - val_loss: 1.8428 - val_acc: 0.4890 - 4s/epoch - 4ms/sample
Epoch 108/200
1088/1088 - 4s - loss: 0.6558 - acc: 0.7803 - val_loss: 1.8707 - val_acc: 0.4743 - 4s/epoch - 3ms/sample
Epoch 109/200
1088/1088 - 4s - loss: 0.6831 - acc: 0.7721 - val_loss: 1.8886 - val_acc: 0.4853 - 4s/epoch - 4ms/sample
Epoch 110/200
1088/1088 - 7s - loss: 0.6341 - acc: 0.7877 - val_loss: 1.9005 - val_acc: 0.4853 - 7s/epoch - 6ms/sample
Epoch 111/200
1088/1088 - 7s - loss: 0.6177 - acc: 0.7886 - val_loss: 1.8858 - val_acc: 0.5000 - 7s/epoch - 6ms/sample
Epoch 112/200
1088/1088 - 6s - loss: 0.6194 - acc: 0.7914 - val_loss: 1.9390 - val_acc: 0.4632 - 6s/epoch - 5ms/sample
Epoch 113/200
1088/1088 - 8s - loss: 0.6536 - acc: 0.7932 - val_loss: 1.9205 - val_acc: 0.4669 - 8s/epoch - 8ms/sample
Epoch 114/200
1088/1088 - 7s - loss: 0.6016 - acc: 0.7950 - val_loss: 1.8944 - val_acc: 0.4816 - 7s/epoch - 6ms/sample
Epoch 115/200
1088/1088 - 4s - loss: 0.6275 - acc: 0.7914 - val_loss: 1.9154 - val_acc: 0.4743 - 4s/epoch - 4ms/sample
Epoch 116/200
1088/1088 - 4s - loss: 0.5651 - acc: 0.8088 - val_loss: 1.9594 - val_acc: 0.4816 - 4s/epoch - 4ms/sample
Epoch 117/200
1088/1088 - 4s - loss: 0.5459 - acc: 0.8290 - val_loss: 1.9580 - val_acc: 0.4816 - 4s/epoch - 3ms/sample
Epoch 118/200
1088/1088 - 4s - loss: 0.5154 - acc: 0.8254 - val_loss: 1.9430 - val_acc: 0.4779 - 4s/epoch - 4ms/sample
Epoch 119/200
1088/1088 - 4s - loss: 0.5107 - acc: 0.8290 - val_loss: 1.9473 - val_acc: 0.4890 - 4s/epoch - 3ms/sample
Epoch 120/200
1088/1088 - 3s - loss: 0.5089 - acc: 0.8419 - val_loss: 1.9948 - val_acc: 0.4706 - 3s/epoch - 3ms/sample
Epoch 121/200
1088/1088 - 4s - loss: 0.5515 - acc: 0.8153 - val_loss: 2.0211 - val_acc: 0.4743 - 4s/epoch - 4ms/sample
Epoch 122/200
1088/1088 - 4s - loss: 0.5090 - acc: 0.8373 - val_loss: 1.9935 - val_acc: 0.4926 - 4s/epoch - 4ms/sample
Epoch 123/200
1088/1088 - 4s - loss: 0.5515 - acc: 0.8015 - val_loss: 1.9860 - val_acc: 0.4926 - 4s/epoch - 4ms/sample
Epoch 124/200
1088/1088 - 3s - loss: 0.4923 - acc: 0.8336 - val_loss: 2.0060 - val_acc: 0.4816 - 3s/epoch - 3ms/sample
Epoch 125/200
1088/1088 - 4s - loss: 0.5175 - acc: 0.8327 - val_loss: 2.0672 - val_acc: 0.4853 - 4s/epoch - 4ms/sample
Epoch 126/200
1088/1088 - 4s - loss: 0.5128 - acc: 0.8336 - val_loss: 2.0909 - val_acc: 0.4522 - 4s/epoch - 3ms/sample
Epoch 127/200
1088/1088 - 4s - loss: 0.4965 - acc: 0.8447 - val_loss: 2.0991 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 128/200
1088/1088 - 4s - loss: 0.4471 - acc: 0.8594 - val_loss: 2.1180 - val_acc: 0.4596 - 4s/epoch - 3ms/sample
Epoch 129/200
1088/1088 - 4s - loss: 0.5202 - acc: 0.8217 - val_loss: 2.1856 - val_acc: 0.4706 - 4s/epoch - 3ms/sample
Epoch 130/200
1088/1088 - 4s - loss: 0.4978 - acc: 0.8438 - val_loss: 2.2066 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 131/200
1088/1088 - 4s - loss: 0.5170 - acc: 0.8171 - val_loss: 2.1492 - val_acc: 0.4596 - 4s/epoch - 4ms/sample
Epoch 132/200
1088/1088 - 4s - loss: 0.4822 - acc: 0.8447 - val_loss: 2.1741 - val_acc: 0.4669 - 4s/epoch - 4ms/sample
Epoch 133/200
1088/1088 - 4s - loss: 0.4708 - acc: 0.8428 - val_loss: 2.1703 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 134/200
1088/1088 - 3s - loss: 0.5105 - acc: 0.8254 - val_loss: 2.1540 - val_acc: 0.4853 - 3s/epoch - 3ms/sample
Epoch 135/200
1088/1088 - 4s - loss: 0.4758 - acc: 0.8456 - val_loss: 2.1859 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 136/200
1088/1088 - 3s - loss: 0.4748 - acc: 0.8318 - val_loss: 2.1311 - val_acc: 0.4485 - 3s/epoch - 3ms/sample
Epoch 137/200
1088/1088 - 4s - loss: 0.4563 - acc: 0.8529 - val_loss: 2.1461 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 138/200
1088/1088 - 4s - loss: 0.4427 - acc: 0.8493 - val_loss: 2.1310 - val_acc: 0.4632 - 4s/epoch - 3ms/sample
Epoch 139/200
1088/1088 - 4s - loss: 0.3771 - acc: 0.8860 - val_loss: 2.1262 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 140/200
1088/1088 - 4s - loss: 0.4334 - acc: 0.8529 - val_loss: 2.0800 - val_acc: 0.5000 - 4s/epoch - 3ms/sample
Epoch 141/200
1088/1088 - 4s - loss: 0.3865 - acc: 0.8695 - val_loss: 2.1105 - val_acc: 0.4890 - 4s/epoch - 3ms/sample
Epoch 142/200
1088/1088 - 3s - loss: 0.4676 - acc: 0.8585 - val_loss: 2.1336 - val_acc: 0.4706 - 3s/epoch - 3ms/sample
Epoch 143/200
1088/1088 - 4s - loss: 0.4388 - acc: 0.8603 - val_loss: 2.1604 - val_acc: 0.4596 - 4s/epoch - 3ms/sample
Epoch 144/200
1088/1088 - 3s - loss: 0.4545 - acc: 0.8603 - val_loss: 2.1396 - val_acc: 0.4743 - 3s/epoch - 3ms/sample
Epoch 145/200
1088/1088 - 4s - loss: 0.4167 - acc: 0.8713 - val_loss: 2.1647 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 146/200
1088/1088 - 3s - loss: 0.4256 - acc: 0.8548 - val_loss: 2.2233 - val_acc: 0.4632 - 3s/epoch - 3ms/sample
Epoch 147/200
1088/1088 - 3s - loss: 0.4160 - acc: 0.8649 - val_loss: 2.3034 - val_acc: 0.4779 - 3s/epoch - 3ms/sample
Epoch 148/200
1088/1088 - 3s - loss: 0.3892 - acc: 0.8750 - val_loss: 2.2639 - val_acc: 0.4779 - 3s/epoch - 3ms/sample
Epoch 149/200
1088/1088 - 3s - loss: 0.4601 - acc: 0.8511 - val_loss: 2.2322 - val_acc: 0.5000 - 3s/epoch - 3ms/sample
Epoch 150/200
1088/1088 - 4s - loss: 0.3508 - acc: 0.8897 - val_loss: 2.2322 - val_acc: 0.4779 - 4s/epoch - 4ms/sample
Epoch 151/200
1088/1088 - 5s - loss: 0.3677 - acc: 0.8860 - val_loss: 2.2449 - val_acc: 0.4596 - 5s/epoch - 4ms/sample
Epoch 152/200
1088/1088 - 4s - loss: 0.4038 - acc: 0.8539 - val_loss: 2.2778 - val_acc: 0.4596 - 4s/epoch - 3ms/sample
Epoch 153/200
1088/1088 - 4s - loss: 0.3396 - acc: 0.8980 - val_loss: 2.2765 - val_acc: 0.4559 - 4s/epoch - 3ms/sample
Epoch 154/200
1088/1088 - 4s - loss: 0.4003 - acc: 0.8621 - val_loss: 2.2802 - val_acc: 0.4412 - 4s/epoch - 3ms/sample
Epoch 155/200
1088/1088 - 3s - loss: 0.3395 - acc: 0.8980 - val_loss: 2.3277 - val_acc: 0.4449 - 3s/epoch - 3ms/sample
Epoch 156/200
1088/1088 - 4s - loss: 0.3455 - acc: 0.8824 - val_loss: 2.3198 - val_acc: 0.4632 - 4s/epoch - 3ms/sample
Epoch 157/200
1088/1088 - 4s - loss: 0.3666 - acc: 0.8925 - val_loss: 2.3948 - val_acc: 0.4596 - 4s/epoch - 4ms/sample
Epoch 158/200
1088/1088 - 3s - loss: 0.3721 - acc: 0.8732 - val_loss: 2.5082 - val_acc: 0.4743 - 3s/epoch - 3ms/sample
Epoch 159/200
1088/1088 - 4s - loss: 0.4203 - acc: 0.8649 - val_loss: 2.3974 - val_acc: 0.4706 - 4s/epoch - 3ms/sample
Epoch 160/200
1088/1088 - 4s - loss: 0.3904 - acc: 0.8713 - val_loss: 2.3471 - val_acc: 0.4559 - 4s/epoch - 3ms/sample
Epoch 161/200
1088/1088 - 5s - loss: 0.3712 - acc: 0.8796 - val_loss: 2.4011 - val_acc: 0.4375 - 5s/epoch - 5ms/sample
Epoch 162/200
1088/1088 - 4s - loss: 0.3659 - acc: 0.8906 - val_loss: 2.3739 - val_acc: 0.4485 - 4s/epoch - 3ms/sample
Epoch 163/200
1088/1088 - 4s - loss: 0.3152 - acc: 0.9062 - val_loss: 2.3663 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 164/200
1088/1088 - 4s - loss: 0.3298 - acc: 0.8943 - val_loss: 2.3808 - val_acc: 0.4632 - 4s/epoch - 3ms/sample
Epoch 165/200
1088/1088 - 4s - loss: 0.3287 - acc: 0.8915 - val_loss: 2.3788 - val_acc: 0.4669 - 4s/epoch - 4ms/sample
Epoch 166/200
1088/1088 - 4s - loss: 0.3580 - acc: 0.9017 - val_loss: 2.3736 - val_acc: 0.4743 - 4s/epoch - 4ms/sample
Epoch 167/200
1088/1088 - 4s - loss: 0.3168 - acc: 0.9017 - val_loss: 2.3478 - val_acc: 0.4963 - 4s/epoch - 3ms/sample
Epoch 168/200
1088/1088 - 4s - loss: 0.3051 - acc: 0.8971 - val_loss: 2.3847 - val_acc: 0.5037 - 4s/epoch - 4ms/sample
Epoch 169/200
1088/1088 - 4s - loss: 0.3036 - acc: 0.8971 - val_loss: 2.4521 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 170/200
1088/1088 - 4s - loss: 0.3226 - acc: 0.9062 - val_loss: 2.4865 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 171/200
1088/1088 - 4s - loss: 0.3437 - acc: 0.8961 - val_loss: 2.5118 - val_acc: 0.4485 - 4s/epoch - 3ms/sample
Epoch 172/200
1088/1088 - 4s - loss: 0.3511 - acc: 0.8934 - val_loss: 2.4866 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 173/200
1088/1088 - 4s - loss: 0.3642 - acc: 0.8888 - val_loss: 2.4987 - val_acc: 0.4596 - 4s/epoch - 3ms/sample
Epoch 174/200
1088/1088 - 4s - loss: 0.3726 - acc: 0.8768 - val_loss: 2.5325 - val_acc: 0.4522 - 4s/epoch - 3ms/sample
Epoch 175/200
1088/1088 - 4s - loss: 0.3273 - acc: 0.8980 - val_loss: 2.4940 - val_acc: 0.4596 - 4s/epoch - 4ms/sample
Epoch 176/200
1088/1088 - 4s - loss: 0.3348 - acc: 0.8888 - val_loss: 2.4204 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 177/200
1088/1088 - 4s - loss: 0.3624 - acc: 0.8851 - val_loss: 2.4324 - val_acc: 0.4706 - 4s/epoch - 3ms/sample
Epoch 178/200
1088/1088 - 4s - loss: 0.3382 - acc: 0.9007 - val_loss: 2.4894 - val_acc: 0.4412 - 4s/epoch - 3ms/sample
Epoch 179/200
1088/1088 - 4s - loss: 0.3628 - acc: 0.8888 - val_loss: 2.4552 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 180/200
1088/1088 - 4s - loss: 0.2984 - acc: 0.9062 - val_loss: 2.4464 - val_acc: 0.4779 - 4s/epoch - 4ms/sample
Epoch 181/200
1088/1088 - 5s - loss: 0.3266 - acc: 0.8961 - val_loss: 2.4580 - val_acc: 0.4743 - 5s/epoch - 4ms/sample
Epoch 182/200
1088/1088 - 6s - loss: 0.3518 - acc: 0.8787 - val_loss: 2.5004 - val_acc: 0.4706 - 6s/epoch - 5ms/sample
Epoch 183/200
1088/1088 - 4s - loss: 0.2961 - acc: 0.9072 - val_loss: 2.4999 - val_acc: 0.4669 - 4s/epoch - 4ms/sample
Epoch 184/200
1088/1088 - 4s - loss: 0.2865 - acc: 0.9127 - val_loss: 2.5375 - val_acc: 0.4596 - 4s/epoch - 4ms/sample
Epoch 185/200
1088/1088 - 4s - loss: 0.2804 - acc: 0.9081 - val_loss: 2.4910 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 186/200
1088/1088 - 4s - loss: 0.2855 - acc: 0.9090 - val_loss: 2.4030 - val_acc: 0.4706 - 4s/epoch - 3ms/sample
Epoch 187/200
1088/1088 - 5s - loss: 0.2884 - acc: 0.9136 - val_loss: 2.3342 - val_acc: 0.4669 - 5s/epoch - 5ms/sample
Epoch 188/200
1088/1088 - 4s - loss: 0.2740 - acc: 0.9145 - val_loss: 2.3756 - val_acc: 0.4669 - 4s/epoch - 4ms/sample
Epoch 189/200
1088/1088 - 4s - loss: 0.2825 - acc: 0.9164 - val_loss: 2.4442 - val_acc: 0.4596 - 4s/epoch - 4ms/sample
Epoch 190/200
1088/1088 - 4s - loss: 0.3408 - acc: 0.8998 - val_loss: 2.4708 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 191/200
1088/1088 - 4s - loss: 0.2848 - acc: 0.9127 - val_loss: 2.4964 - val_acc: 0.4669 - 4s/epoch - 3ms/sample
Epoch 192/200
1088/1088 - 4s - loss: 0.2694 - acc: 0.9154 - val_loss: 2.4869 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 193/200
1088/1088 - 4s - loss: 0.2918 - acc: 0.9108 - val_loss: 2.5015 - val_acc: 0.4706 - 4s/epoch - 4ms/sample
Epoch 194/200
1088/1088 - 4s - loss: 0.2708 - acc: 0.9154 - val_loss: 2.5763 - val_acc: 0.4890 - 4s/epoch - 4ms/sample
Epoch 195/200
1088/1088 - 4s - loss: 0.2580 - acc: 0.9182 - val_loss: 2.5788 - val_acc: 0.4926 - 4s/epoch - 4ms/sample
Epoch 196/200
1088/1088 - 4s - loss: 0.2501 - acc: 0.9292 - val_loss: 2.5750 - val_acc: 0.4816 - 4s/epoch - 3ms/sample
Epoch 197/200
1088/1088 - 4s - loss: 0.2711 - acc: 0.9301 - val_loss: 2.6065 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 198/200
1088/1088 - 4s - loss: 0.3012 - acc: 0.9127 - val_loss: 2.6151 - val_acc: 0.4559 - 4s/epoch - 4ms/sample
Epoch 199/200
1088/1088 - 4s - loss: 0.2551 - acc: 0.9219 - val_loss: 2.5627 - val_acc: 0.4632 - 4s/epoch - 4ms/sample
Epoch 200/200
1088/1088 - 3s - loss: 0.2442 - acc: 0.9210 - val_loss: 2.4547 - val_acc: 0.4743 - 3s/epoch - 3ms/sample
In [36]:
# predicting the model2 on test data
y_pred=model2.predict(X_test)
In [37]:
# Capturing learning history per epoch
hist  = pd.DataFrame(history2.history)
hist['epoch'] = history2.epoch

# Plotting accuracy at different epochs
plt.plot(hist['loss'])
plt.plot(hist['val_loss'])
plt.legend(("train" , "valid") , loc =0)

# Printing results
results = model2.evaluate(X_test, y_test)
No description has been provided for this image
In [38]:
# Capturing learning history per epoch
hist  = pd.DataFrame(history2.history)
hist['epoch'] = history2.epoch

# Plotting accuracy at different epochs
plt.plot(hist['acc'])
plt.plot(hist['val_acc'])
plt.legend(("train" , "valid") , loc =0)

# Printing results
results = model2.evaluate(X_test, y_test)
No description has been provided for this image
In [39]:
# Classification Accuracy
print("Classification Accuracy:")
print('Loss and Accuracy on Training data:',model2.evaluate(X_train, y_train))
print('Loss and Accuracy on Test data:',model2.evaluate(X_test, y_test))
print()

# Classification Report
print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# Confusion Matrix
print("Confusion Matrix Chart:")
cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
df_cm = pd.DataFrame(cm, index = [i for i in ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16']],  
                         columns = [i for i in ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16']])
plt.figure(figsize = (12,10))
sns.heatmap(df_cm, annot=True, fmt='g')
plt.title('Confusion Matrix')
plt.ylabel('Actual Label')
plt.xlabel('Predicted Label')
plt.show()
Classification Accuracy:
Loss and Accuracy on Training data: [0.009807920562760794, 0.9990809]
Loss and Accuracy on Test data: [2.454698555609759, 0.4742647]

Classification Report:
               precision    recall  f1-score   support

           0       0.21      0.57      0.31        14
           1       0.38      0.18      0.24        17
           2       0.73      0.73      0.73        15
           3       0.75      0.25      0.38        12
           4       0.54      0.44      0.48        16
           5       0.13      0.13      0.13        15
           6       0.41      0.50      0.45        14
           7       0.67      0.62      0.64        13
           8       0.60      0.56      0.58        16
           9       0.59      0.56      0.57        18
          10       0.29      0.30      0.29        20
          11       0.40      0.50      0.44        12
          12       0.74      0.70      0.72        20
          13       0.67      0.35      0.46        17
          14       0.31      0.24      0.27        21
          15       0.42      0.67      0.51        15
          16       1.00      0.82      0.90        17

    accuracy                           0.47       272
   macro avg       0.52      0.48      0.48       272
weighted avg       0.52      0.47      0.48       272

Confusion Matrix Chart:
No description has been provided for this image

3D. Train a model using a basic CNN and share performance metrics on test data.¶

In [40]:
# Split the data for training and testing
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
In [41]:
print(X_train.shape,X_test.shape)
print(y_train.shape,y_test.shape)
(1088, 128, 128, 3) (272, 128, 128, 3)
(1088, 17) (272, 17)
In [42]:
generator = ImageDataGenerator(rotation_range = 180,
                               zoom_range = 0.2,
                               width_shift_range = 0.2,
                               height_shift_range = 0.2,
                               horizontal_flip = True,
                               vertical_flip = True)
generator.fit(X_train)
In [43]:
model3 = Sequential()

model3.add(Conv2D(filters=64, kernel_size=(3, 3), input_shape=(128, 128, 3), activation='relu'))
model3.add(MaxPool2D((2, 2)))
# model3.add(Dropout(0.25))

model3.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu'))
model3.add(MaxPool2D((2, 2)))
# model3.add(Dropout(0.25))

model3.add(Flatten())

model3.add(Dense(128, activation='relu'))
# model3.add(Dropout(0.25))

model3.add(Dense(64, activation='relu'))
# model3.add(Dropout(0.25))

model3.add(Dense(17, activation='softmax'))

model3.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

model3.summary()
Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 126, 126, 64)      1792      
                                                                 
 max_pooling2d (MaxPooling2D  (None, 63, 63, 64)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 61, 61, 128)       73856     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 30, 30, 128)      0         
 2D)                                                             
                                                                 
 flatten (Flatten)           (None, 115200)            0         
                                                                 
 dense_5 (Dense)             (None, 128)               14745728  
                                                                 
 dense_6 (Dense)             (None, 64)                8256      
                                                                 
 dense_7 (Dense)             (None, 17)                1105      
                                                                 
=================================================================
Total params: 14,830,737
Trainable params: 14,830,737
Non-trainable params: 0
_________________________________________________________________
In [44]:
history3 = model3.fit(generator.flow(X_train,y_train, batch_size=200), epochs=100, verbose=2, shuffle=True, validation_data=(X_test,y_test))
pd.DataFrame(history3.history)
Epoch 1/100
6/6 - 70s - loss: 3.3924 - acc: 0.0717 - val_loss: 2.7450 - val_acc: 0.0662 - 70s/epoch - 12s/step
Epoch 2/100
6/6 - 65s - loss: 2.7315 - acc: 0.0680 - val_loss: 2.6359 - val_acc: 0.0882 - 65s/epoch - 11s/step
Epoch 3/100
6/6 - 63s - loss: 2.6147 - acc: 0.1094 - val_loss: 2.4474 - val_acc: 0.1471 - 63s/epoch - 10s/step
Epoch 4/100
6/6 - 67s - loss: 2.4862 - acc: 0.1324 - val_loss: 2.2456 - val_acc: 0.2426 - 67s/epoch - 11s/step
Epoch 5/100
6/6 - 62s - loss: 2.3572 - acc: 0.1857 - val_loss: 2.1577 - val_acc: 0.2610 - 62s/epoch - 10s/step
Epoch 6/100
6/6 - 65s - loss: 2.2333 - acc: 0.2601 - val_loss: 1.9936 - val_acc: 0.2904 - 65s/epoch - 11s/step
Epoch 7/100
6/6 - 63s - loss: 2.1573 - acc: 0.2693 - val_loss: 1.8763 - val_acc: 0.3787 - 63s/epoch - 10s/step
Epoch 8/100
6/6 - 62s - loss: 2.0143 - acc: 0.3447 - val_loss: 1.7254 - val_acc: 0.3897 - 62s/epoch - 10s/step
Epoch 9/100
6/6 - 70s - loss: 1.9153 - acc: 0.3529 - val_loss: 1.6644 - val_acc: 0.4081 - 70s/epoch - 12s/step
Epoch 10/100
6/6 - 64s - loss: 1.8566 - acc: 0.3741 - val_loss: 1.5581 - val_acc: 0.4706 - 64s/epoch - 11s/step
Epoch 11/100
6/6 - 64s - loss: 1.7618 - acc: 0.4044 - val_loss: 1.5114 - val_acc: 0.4559 - 64s/epoch - 11s/step
Epoch 12/100
6/6 - 61s - loss: 1.6709 - acc: 0.4485 - val_loss: 1.4587 - val_acc: 0.5000 - 61s/epoch - 10s/step
Epoch 13/100
6/6 - 64s - loss: 1.6066 - acc: 0.4439 - val_loss: 1.3360 - val_acc: 0.5257 - 64s/epoch - 11s/step
Epoch 14/100
6/6 - 62s - loss: 1.5183 - acc: 0.4871 - val_loss: 1.3502 - val_acc: 0.5735 - 62s/epoch - 10s/step
Epoch 15/100
6/6 - 65s - loss: 1.4923 - acc: 0.5055 - val_loss: 1.3019 - val_acc: 0.5515 - 65s/epoch - 11s/step
Epoch 16/100
6/6 - 64s - loss: 1.4563 - acc: 0.5129 - val_loss: 1.3257 - val_acc: 0.5735 - 64s/epoch - 11s/step
Epoch 17/100
6/6 - 64s - loss: 1.3976 - acc: 0.5276 - val_loss: 1.3548 - val_acc: 0.5257 - 64s/epoch - 11s/step
Epoch 18/100
6/6 - 69s - loss: 1.4153 - acc: 0.5312 - val_loss: 1.2963 - val_acc: 0.5699 - 69s/epoch - 12s/step
Epoch 19/100
6/6 - 63s - loss: 1.3802 - acc: 0.5460 - val_loss: 1.2312 - val_acc: 0.5846 - 63s/epoch - 10s/step
Epoch 20/100
6/6 - 65s - loss: 1.3257 - acc: 0.5542 - val_loss: 1.2463 - val_acc: 0.5882 - 65s/epoch - 11s/step
Epoch 21/100
6/6 - 63s - loss: 1.3048 - acc: 0.5460 - val_loss: 1.1593 - val_acc: 0.6287 - 63s/epoch - 11s/step
Epoch 22/100
6/6 - 65s - loss: 1.2927 - acc: 0.5570 - val_loss: 1.2447 - val_acc: 0.6103 - 65s/epoch - 11s/step
Epoch 23/100
6/6 - 63s - loss: 1.3448 - acc: 0.5377 - val_loss: 1.3965 - val_acc: 0.5000 - 63s/epoch - 10s/step
Epoch 24/100
6/6 - 62s - loss: 1.3122 - acc: 0.5625 - val_loss: 1.2049 - val_acc: 0.5846 - 62s/epoch - 10s/step
Epoch 25/100
6/6 - 65s - loss: 1.2494 - acc: 0.5836 - val_loss: 1.2981 - val_acc: 0.5441 - 65s/epoch - 11s/step
Epoch 26/100
6/6 - 63s - loss: 1.1908 - acc: 0.5864 - val_loss: 1.1660 - val_acc: 0.6324 - 63s/epoch - 10s/step
Epoch 27/100
6/6 - 65s - loss: 1.1757 - acc: 0.5947 - val_loss: 1.1470 - val_acc: 0.5699 - 65s/epoch - 11s/step
Epoch 28/100
6/6 - 69s - loss: 1.1583 - acc: 0.5892 - val_loss: 1.1628 - val_acc: 0.6103 - 69s/epoch - 11s/step
Epoch 29/100
6/6 - 66s - loss: 1.1555 - acc: 0.6094 - val_loss: 1.1431 - val_acc: 0.5993 - 66s/epoch - 11s/step
Epoch 30/100
6/6 - 64s - loss: 1.1583 - acc: 0.5882 - val_loss: 1.1758 - val_acc: 0.6213 - 64s/epoch - 11s/step
Epoch 31/100
6/6 - 66s - loss: 1.1625 - acc: 0.5938 - val_loss: 1.2844 - val_acc: 0.5919 - 66s/epoch - 11s/step
Epoch 32/100
6/6 - 64s - loss: 1.1326 - acc: 0.6121 - val_loss: 1.2678 - val_acc: 0.5699 - 64s/epoch - 11s/step
Epoch 33/100
6/6 - 63s - loss: 1.1014 - acc: 0.6204 - val_loss: 1.4632 - val_acc: 0.5184 - 63s/epoch - 11s/step
Epoch 34/100
6/6 - 65s - loss: 1.0620 - acc: 0.6213 - val_loss: 1.1109 - val_acc: 0.5993 - 65s/epoch - 11s/step
Epoch 35/100
6/6 - 64s - loss: 1.0604 - acc: 0.6397 - val_loss: 1.1264 - val_acc: 0.5294 - 64s/epoch - 11s/step
Epoch 36/100
6/6 - 65s - loss: 1.0801 - acc: 0.6103 - val_loss: 1.1922 - val_acc: 0.6691 - 65s/epoch - 11s/step
Epoch 37/100
6/6 - 68s - loss: 1.0408 - acc: 0.6526 - val_loss: 1.3192 - val_acc: 0.5588 - 68s/epoch - 11s/step
Epoch 38/100
6/6 - 65s - loss: 1.0034 - acc: 0.6618 - val_loss: 1.2485 - val_acc: 0.6213 - 65s/epoch - 11s/step
Epoch 39/100
6/6 - 63s - loss: 1.0246 - acc: 0.6388 - val_loss: 1.0378 - val_acc: 0.6691 - 63s/epoch - 11s/step
Epoch 40/100
6/6 - 63s - loss: 1.0232 - acc: 0.6553 - val_loss: 1.0987 - val_acc: 0.6434 - 63s/epoch - 10s/step
Epoch 41/100
6/6 - 65s - loss: 1.0155 - acc: 0.6471 - val_loss: 1.1394 - val_acc: 0.6618 - 65s/epoch - 11s/step
Epoch 42/100
6/6 - 63s - loss: 0.9563 - acc: 0.6746 - val_loss: 1.0549 - val_acc: 0.6250 - 63s/epoch - 10s/step
Epoch 43/100
6/6 - 65s - loss: 0.9533 - acc: 0.6737 - val_loss: 1.1270 - val_acc: 0.6581 - 65s/epoch - 11s/step
Epoch 44/100
6/6 - 65s - loss: 0.9416 - acc: 0.6893 - val_loss: 1.1917 - val_acc: 0.6029 - 65s/epoch - 11s/step
Epoch 45/100
6/6 - 68s - loss: 0.9689 - acc: 0.6599 - val_loss: 1.2172 - val_acc: 0.5772 - 68s/epoch - 11s/step
Epoch 46/100
6/6 - 68s - loss: 0.9384 - acc: 0.6866 - val_loss: 1.2297 - val_acc: 0.6066 - 68s/epoch - 11s/step
Epoch 47/100
6/6 - 67s - loss: 0.9181 - acc: 0.6857 - val_loss: 1.1366 - val_acc: 0.6434 - 67s/epoch - 11s/step
Epoch 48/100
6/6 - 65s - loss: 0.9647 - acc: 0.6719 - val_loss: 0.9815 - val_acc: 0.6801 - 65s/epoch - 11s/step
Epoch 49/100
6/6 - 63s - loss: 0.9668 - acc: 0.6783 - val_loss: 0.9163 - val_acc: 0.6765 - 63s/epoch - 10s/step
Epoch 50/100
6/6 - 64s - loss: 0.9155 - acc: 0.6866 - val_loss: 1.1279 - val_acc: 0.6360 - 64s/epoch - 11s/step
Epoch 51/100
6/6 - 63s - loss: 0.8526 - acc: 0.7077 - val_loss: 1.0544 - val_acc: 0.6618 - 63s/epoch - 10s/step
Epoch 52/100
6/6 - 65s - loss: 0.9292 - acc: 0.6921 - val_loss: 1.0119 - val_acc: 0.6765 - 65s/epoch - 11s/step
Epoch 53/100
6/6 - 63s - loss: 0.9748 - acc: 0.6425 - val_loss: 1.1168 - val_acc: 0.6360 - 63s/epoch - 10s/step
Epoch 54/100
6/6 - 63s - loss: 0.9239 - acc: 0.6838 - val_loss: 1.0740 - val_acc: 0.6618 - 63s/epoch - 10s/step
Epoch 55/100
6/6 - 64s - loss: 0.8887 - acc: 0.7004 - val_loss: 0.9733 - val_acc: 0.6728 - 64s/epoch - 11s/step
Epoch 56/100
6/6 - 68s - loss: 0.8735 - acc: 0.7004 - val_loss: 1.0008 - val_acc: 0.6765 - 68s/epoch - 11s/step
Epoch 57/100
6/6 - 66s - loss: 0.8424 - acc: 0.7077 - val_loss: 1.0485 - val_acc: 0.6544 - 66s/epoch - 11s/step
Epoch 58/100
6/6 - 64s - loss: 0.8262 - acc: 0.7123 - val_loss: 1.2350 - val_acc: 0.6066 - 64s/epoch - 11s/step
Epoch 59/100
6/6 - 67s - loss: 0.8483 - acc: 0.7105 - val_loss: 1.0702 - val_acc: 0.6801 - 67s/epoch - 11s/step
Epoch 60/100
6/6 - 64s - loss: 0.8805 - acc: 0.6976 - val_loss: 0.9601 - val_acc: 0.6985 - 64s/epoch - 11s/step
Epoch 61/100
6/6 - 64s - loss: 0.8274 - acc: 0.7151 - val_loss: 0.9729 - val_acc: 0.6875 - 64s/epoch - 11s/step
Epoch 62/100
6/6 - 66s - loss: 0.8447 - acc: 0.7059 - val_loss: 0.9164 - val_acc: 0.6949 - 66s/epoch - 11s/step
Epoch 63/100
6/6 - 63s - loss: 0.8480 - acc: 0.7013 - val_loss: 0.9536 - val_acc: 0.7206 - 63s/epoch - 10s/step
Epoch 64/100
6/6 - 65s - loss: 0.8667 - acc: 0.7068 - val_loss: 0.9644 - val_acc: 0.6728 - 65s/epoch - 11s/step
Epoch 65/100
6/6 - 68s - loss: 0.8558 - acc: 0.7004 - val_loss: 0.9900 - val_acc: 0.6985 - 68s/epoch - 11s/step
Epoch 66/100
6/6 - 67s - loss: 0.7899 - acc: 0.7188 - val_loss: 1.0286 - val_acc: 0.6581 - 67s/epoch - 11s/step
Epoch 67/100
6/6 - 63s - loss: 0.7829 - acc: 0.7197 - val_loss: 1.1121 - val_acc: 0.6250 - 63s/epoch - 11s/step
Epoch 68/100
6/6 - 63s - loss: 0.7621 - acc: 0.7289 - val_loss: 0.9459 - val_acc: 0.6544 - 63s/epoch - 10s/step
Epoch 69/100
6/6 - 65s - loss: 0.7612 - acc: 0.7362 - val_loss: 1.1378 - val_acc: 0.6324 - 65s/epoch - 11s/step
Epoch 70/100
6/6 - 65s - loss: 0.7287 - acc: 0.7381 - val_loss: 1.0132 - val_acc: 0.6912 - 65s/epoch - 11s/step
Epoch 71/100
6/6 - 66s - loss: 0.7560 - acc: 0.7279 - val_loss: 0.9778 - val_acc: 0.6801 - 66s/epoch - 11s/step
Epoch 72/100
6/6 - 64s - loss: 0.6834 - acc: 0.7831 - val_loss: 1.1057 - val_acc: 0.6728 - 64s/epoch - 11s/step
Epoch 73/100
6/6 - 67s - loss: 0.7887 - acc: 0.7151 - val_loss: 0.9562 - val_acc: 0.6838 - 67s/epoch - 11s/step
Epoch 74/100
6/6 - 63s - loss: 0.7547 - acc: 0.7307 - val_loss: 0.9675 - val_acc: 0.6949 - 63s/epoch - 11s/step
Epoch 75/100
6/6 - 70s - loss: 0.7691 - acc: 0.7169 - val_loss: 1.0586 - val_acc: 0.6618 - 70s/epoch - 12s/step
Epoch 76/100
6/6 - 66s - loss: 0.7221 - acc: 0.7610 - val_loss: 1.0732 - val_acc: 0.6471 - 66s/epoch - 11s/step
Epoch 77/100
6/6 - 63s - loss: 0.7161 - acc: 0.7463 - val_loss: 1.1408 - val_acc: 0.6213 - 63s/epoch - 10s/step
Epoch 78/100
6/6 - 66s - loss: 0.7261 - acc: 0.7454 - val_loss: 0.9609 - val_acc: 0.6581 - 66s/epoch - 11s/step
Epoch 79/100
6/6 - 62s - loss: 0.7122 - acc: 0.7381 - val_loss: 1.0080 - val_acc: 0.6728 - 62s/epoch - 10s/step
Epoch 80/100
6/6 - 65s - loss: 0.7042 - acc: 0.7610 - val_loss: 1.1014 - val_acc: 0.6507 - 65s/epoch - 11s/step
Epoch 81/100
6/6 - 64s - loss: 0.6533 - acc: 0.7546 - val_loss: 1.0817 - val_acc: 0.6691 - 64s/epoch - 11s/step
Epoch 82/100
6/6 - 63s - loss: 0.6730 - acc: 0.7656 - val_loss: 1.0262 - val_acc: 0.6654 - 63s/epoch - 11s/step
Epoch 83/100
6/6 - 65s - loss: 0.6543 - acc: 0.7757 - val_loss: 1.1134 - val_acc: 0.6581 - 65s/epoch - 11s/step
Epoch 84/100
6/6 - 71s - loss: 0.6561 - acc: 0.7721 - val_loss: 0.9032 - val_acc: 0.7059 - 71s/epoch - 12s/step
Epoch 85/100
6/6 - 68s - loss: 0.6428 - acc: 0.7721 - val_loss: 1.0667 - val_acc: 0.6544 - 68s/epoch - 11s/step
Epoch 86/100
6/6 - 65s - loss: 0.6610 - acc: 0.7757 - val_loss: 1.1504 - val_acc: 0.6140 - 65s/epoch - 11s/step
Epoch 87/100
6/6 - 67s - loss: 0.6198 - acc: 0.7858 - val_loss: 0.9785 - val_acc: 0.6912 - 67s/epoch - 11s/step
Epoch 88/100
6/6 - 65s - loss: 0.6191 - acc: 0.7812 - val_loss: 1.0919 - val_acc: 0.6581 - 65s/epoch - 11s/step
Epoch 89/100
6/6 - 63s - loss: 0.6239 - acc: 0.7812 - val_loss: 1.1556 - val_acc: 0.6471 - 63s/epoch - 10s/step
Epoch 90/100
6/6 - 66s - loss: 0.6715 - acc: 0.7647 - val_loss: 1.2219 - val_acc: 0.6507 - 66s/epoch - 11s/step
Epoch 91/100
6/6 - 64s - loss: 0.6999 - acc: 0.7528 - val_loss: 0.9965 - val_acc: 0.6691 - 64s/epoch - 11s/step
Epoch 92/100
6/6 - 65s - loss: 0.6676 - acc: 0.7721 - val_loss: 1.0382 - val_acc: 0.6949 - 65s/epoch - 11s/step
Epoch 93/100
6/6 - 62s - loss: 0.6495 - acc: 0.7638 - val_loss: 0.9962 - val_acc: 0.6691 - 62s/epoch - 10s/step
Epoch 94/100
6/6 - 63s - loss: 0.5972 - acc: 0.7978 - val_loss: 1.0171 - val_acc: 0.6765 - 63s/epoch - 11s/step
Epoch 95/100
6/6 - 66s - loss: 0.6052 - acc: 0.7904 - val_loss: 1.0342 - val_acc: 0.6801 - 66s/epoch - 11s/step
Epoch 96/100
6/6 - 68s - loss: 0.5773 - acc: 0.8097 - val_loss: 1.0738 - val_acc: 0.6838 - 68s/epoch - 11s/step
Epoch 97/100
6/6 - 65s - loss: 0.5825 - acc: 0.7895 - val_loss: 1.0203 - val_acc: 0.7022 - 65s/epoch - 11s/step
Epoch 98/100
6/6 - 64s - loss: 0.6273 - acc: 0.7877 - val_loss: 1.0691 - val_acc: 0.6728 - 64s/epoch - 11s/step
Epoch 99/100
6/6 - 66s - loss: 0.6836 - acc: 0.7537 - val_loss: 0.9984 - val_acc: 0.6618 - 66s/epoch - 11s/step
Epoch 100/100
6/6 - 65s - loss: 0.6494 - acc: 0.7629 - val_loss: 1.0135 - val_acc: 0.6581 - 65s/epoch - 11s/step
Out[44]:
loss acc val_loss val_acc
0 3.392384 0.071691 2.745038 0.066176
1 2.731488 0.068015 2.635865 0.088235
2 2.614685 0.109375 2.447363 0.147059
3 2.486161 0.132353 2.245599 0.242647
4 2.357225 0.185662 2.157732 0.261029
... ... ... ... ...
95 0.577338 0.809743 1.073848 0.683824
96 0.582457 0.789522 1.020297 0.702206
97 0.627347 0.787684 1.069094 0.672794
98 0.683557 0.753676 0.998365 0.661765
99 0.649371 0.762868 1.013515 0.658088

100 rows × 4 columns

In [45]:
# Capturing learning history per epoch
hist  = pd.DataFrame(history3.history)
hist['epoch'] = history3.epoch

# Plotting accuracy at different epochs
plt.plot(hist['loss'])
plt.plot(hist['val_loss'])
plt.legend(("train" , "valid") , loc =0)

# Printing results
results = model3.evaluate(X_test, y_test)
No description has been provided for this image
In [46]:
# Capturing learning history per epoch
hist  = pd.DataFrame(history3.history)
hist['epoch'] = history3.epoch

# Plotting accuracy at different epochs
plt.plot(hist['acc'])
plt.plot(hist['val_acc'])
plt.legend(("train" , "valid") , loc =0)

# Printing results
results = model3.evaluate(X_test, y_test)
No description has been provided for this image
In [47]:
y_pred=model3.predict(X_test)
y_pred
Out[47]:
array([[1.4936901e-16, 6.7635947e-13, 4.2394110e-16, ..., 6.8027917e-11,
        9.9985242e-01, 6.5962971e-11],
       [1.9952194e-10, 1.0247657e-04, 2.7318805e-09, ..., 5.2767390e-08,
        6.1428007e-05, 7.0166854e-12],
       [2.4238729e-04, 7.6894343e-01, 2.7806822e-03, ..., 5.2442710e-04,
        2.0040004e-03, 6.9570166e-10],
       ...,
       [1.3448957e-04, 2.0539731e-01, 1.9265990e-06, ..., 2.2757968e-05,
        6.3296938e-03, 2.5160843e-10],
       [4.4570473e-04, 1.0192490e-06, 8.4318322e-01, ..., 6.7324567e-05,
        1.6037774e-06, 1.6794175e-08],
       [1.5384281e-08, 5.1876251e-04, 3.1278800e-05, ..., 3.2141128e-07,
        3.1305814e-01, 2.0987597e-11]], dtype=float32)
In [48]:
# Classification Accuracy
print("Classification Accuracy:")
print('Loss and Accuracy on Training data:',model3.evaluate(X_train, y_train))
print('Loss and Accuracy on Test data:',model3.evaluate(X_test, y_test))
print()

# Classification Report
print("Classification Report:\n",classification_report(y_test.argmax(axis=1), y_pred.argmax(axis=1)))

# Confusion Matrix
print("Confusion Matrix Chart:")
cm = confusion_matrix(y_test.argmax(axis=1), y_pred.argmax(axis=1))
df_cm = pd.DataFrame(cm, index = [i for i in ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16']],  
                         columns = [i for i in ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16']])
plt.figure(figsize = (12,10))
sns.heatmap(df_cm, annot=True, fmt='g')
plt.title('Confusion Matrix')
plt.ylabel('Actual Label')
plt.xlabel('Predicted Label')
plt.show()
Classification Accuracy:
Loss and Accuracy on Training data: [0.536414310336113, 0.7977941]
Loss and Accuracy on Test data: [1.0471456576796139, 0.6580882]

Classification Report:
               precision    recall  f1-score   support

           0       0.43      0.64      0.51        14
           1       0.64      0.82      0.72        17
           2       1.00      0.67      0.80        15
           3       0.39      0.75      0.51        12
           4       0.52      0.81      0.63        16
           5       0.43      0.67      0.53        15
           6       0.78      0.50      0.61        14
           7       0.71      0.77      0.74        13
           8       0.67      0.50      0.57        16
           9       0.92      0.61      0.73        18
          10       0.80      0.80      0.80        20
          11       0.43      0.75      0.55        12
          12       0.83      0.50      0.62        20
          13       1.00      0.88      0.94        17
          14       0.83      0.24      0.37        21
          15       0.80      0.80      0.80        15
          16       0.92      0.65      0.76        17

    accuracy                           0.66       272
   macro avg       0.71      0.67      0.66       272
weighted avg       0.73      0.66      0.66       272

Confusion Matrix Chart:
No description has been provided for this image

3E. Predict the class/label of image ‘Prediction.jpg’ using best performing model and share predicted label.¶

In [49]:
# Function to read images from the given path and predict the image class
import matplotlib.image as mpimg
import keras.utils as image

def imagepredict(path):
    img=mpimg.imread(path)
    plt.imshow(img)
    plt.axis('off')
    plt.show()
    
    # Prediction
    img = image.load_img(path, target_size=(128, 128))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = x.astype('float32')/255
    pred = np.argmax(model3.predict(x))
    print()
    print("Predicted Class of the above image is: {}.".format(pred))
In [50]:
path = '/content/drive/MyDrive/MGL/Project-CV-1/Prediction.jpg'
imagepredict(path)
No description has been provided for this image
Predicted Class of the above image is: 2.
In [68]:
# Using test images from the given dataset
# Test Image as n1
n1 = 21
plt.imshow(X_test[n1])

# y_pred=model1.predict(X_test)

# Actual Class
print("Actual Class:",[y_test.argmax(axis=1)[n1]])
# Predicted Class
print("Predicted Class:",[y_pred.argmax(axis=1)[n1]])
print()
Actual Class: [1]
Predicted Class: [1]

No description has been provided for this image

Additional Models; Not part of the Project Part-B:

CNN with VGG-16¶

  • Flatten
  • 2 dense layers (256, activation='relu')
  • Dropout(0.5)
  • loss='categorical_crossentropy', optimizer='adam'
  • model compile with ImageDataGenerator to minimize overfitting.
  • shuffle = True
In [52]:
# generator = ImageDataGenerator(rotation_range = 180,
#                                zoom_range = 0.2,
#                                width_shift_range = 0.2,
#                                height_shift_range = 0.2,
#                                horizontal_flip = True,
#                                vertical_flip = True)
# generator.fit(X_train)
In [53]:
# from keras.applications.vgg16 import VGG16

# # Initialize the VGG-16 model
# # Remove the final layer of the model and add 12 classess of plant seedlings
# # Input images: 128px by 128px.

# prior_model = VGG16(weights='imagenet',include_top=False, input_shape=(128,128,3))

# # Lets create our model

# model4 = Sequential()

# # Here we add a all the VGG16 as a layer

# model4.add(prior_model)
In [54]:
# model4.summary()
In [55]:
# model4.layers[0].summary()
In [56]:
# model4.add(Flatten())
# model4.add(Dense(256,activation='relu'))
# model4.add(Dropout(0.5))
# model4.add(Dense(17, activation='softmax'))
In [57]:
# model4.summary()
In [58]:
# # Looping over each layers in layer 0 to freeze them
# for layers in model4.layers[0].layers: 
#   layers.trainable = False

# # Freezing layer 0 as well for good measure
# model4.layers[0].trainable = False 
In [59]:
# model4.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
In [60]:
# history4 = model4.fit(generator.flow(X_train,y_train,batch_size=300), epochs=100, verbose=2, shuffle=True, validation_data=(X_test,y_test))
# pd.DataFrame(history4.history)

CNN with InceptionV3¶

  • Flatten
  • 2 dense layers (1024, activation='relu')
  • Dropout(0.5)
  • loss='categorical_crossentropy', optimizer='adam'
  • model compile with ImageDataGenerator to minimize overfitting.
  • shuffle = True
In [61]:
# from keras.applications.inception_v3 import InceptionV3

# # Initialize the InceptionV3 model
# # Remove the final layer of the model and add 12 classess of plant seedlings
# # Input images: 128px by 128px.

# prior_model = InceptionV3(weights='imagenet',include_top=False, input_shape=(128,128,3))

# # Lets create our model

# model5 = Sequential()

# # Here we add a all the InceptionV3 as a layer

# model5.add(prior_model)
In [62]:
# model5.summary()
In [63]:
# model5.layers[0].summary()
In [64]:
# model5.add(Flatten())

# model5.add(Dense(1024, activation='relu'))
# model5.add(Dropout(0.5))

# model5.add(Dense(17, activation='softmax'))

# model5.summary()
In [65]:
# # Looping over each layers in layer 0 to freeze them
# for layers in model5.layers[0].layers: 
#   layers.trainable = False

# # freezing layer 0 as well for good measure
# model5.layers[0].trainable = False 
In [66]:
# model5.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
In [67]:
# history5 = model5.fit(generator.flow(X_train,y_train,batch_size=300), epochs=100, verbose=2,shuffle=True,validation_data=(X_test,y_test))
# pd.DataFrame(history5.history)

References:¶

  1. Towards Data Science
  2. Kaggle. Kaggle Code
  3. KdNuggets
  4. AnalyticsVidhya
  5. Wikipedia
  6. Numpy
  7. Pandas
  8. SciPy
  9. MatplotLib
  10. Seaborn
  11. Python
  12. Plotly
  13. Bokeh
  14. RStudio
  15. MiniTab
  16. Anaconda
  17. PapersWithCode